<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[gutocarvalho.net]]></title>
  <link href="http://gutocarvalho.net/octopress/atom.xml" rel="self"/>
  <link href="http://gutocarvalho.net/octopress/"/>
  <updated>2013-05-21T20:08:34-03:00</updated>
  <id>http://gutocarvalho.net/octopress/</id>
  <author>
    <name><![CDATA[Guto Carvalho]]></name>
    <email><![CDATA[gutocarvalho@gmail.com]]></email>
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Copy APP]]></title>
    <link href="http://gutocarvalho.net/octopress/2013/05/21/copy-app/"/>
    <updated>2013-05-21T11:41:00-03:00</updated>
    <id>http://gutocarvalho.net/octopress/2013/05/21/copy-app</id>
    <content type="html"><![CDATA[<h2>1. Cloud Storage com o COPY</h2>

<p>Ontem eu encontrei um post no Google Plus falando sobre a APP <a href="https://www.copy.com/home/?r=X36W03&amp;signup=1">COPY</a>, quando olhei, eu pensei que fosse mais uma dessas APP de CLOUD Storage que vão me oferecer míseros 2 gigas, algo que não vale a pena investir já que uso o Dropbox e tenho cerca de 18 gigas atualmente (tudo na base de invites), contudo, vi que eles anunciaram 15GB de cara, isso me deixou bastante interessado e fui olhar de perto.</p>

<p>Por trás do COPY está a empresa <a href="https://www.barracuda.com/">Barracuda Networks</a> que possui uma grande experiência com serviços de segurança, rede, armazenamento e backup. No lançamento do COPY eles estavam oferecendo apenas 5 gigas, mas agora estão mais agressivos oferecendo 15 gigas já de início.</p>

<p>A COPY parece ser o primeiro concorrente para valer do DROPBOX, a aplicação é praticamente um clone, tem todas as features do DROPBOX e oferece uma interface web mais polida, além disto, há uma integração com as principais redes sociais (Google Plus, Facebook e Twitter).</p>

<p>Veja abaixo um vídeo sobre o COPY:</p>

<iframe width="560" height="315" src="http://www.youtube.com/embed/m36ZMdE-vro" frameborder="0" allowfullscreen></iframe>


<h2>2. Sincronização</h2>

<p>De ontem para hoje eu instalei no Macbook Pro, Android, IOS e no IMac, já sincronizei dados entre os dispositivos, subi arquivos pequenos e subi uma discografia de 1 GB com vários arquivos mp3, a discografia subiu em menos de 10 minutos, nem preciso dizer que o DROPBOX fica muito atrás na velocidade de UPLOAD e também na velocidade de DOWNLOAD (apesar de ser um ótimo serviço). O Download da discografia em outro dispositivo levou cerca de 25 minutos, demorou mais para descer do que para subir.</p>

<h3>2.1 Notificações</h3>

<p>Senti falta dos indicadores e notificações nos ícones como temos no DROPBOX, algo como  já foi sincronizado (verde), sincronizando (amarelo), isso o Copy ainda não tem.</p>

<h3>2.2 Pause Sync</h3>

<p>Esse recurso é essencial, não tem no em várias apps de cloud storage, mas vem nativamente no COPY, com isso, se quisermos parar por alguma razão a sincronização é só clicar no PAUSE, acredite, isto é muito útil.</p>

<h2>3. Pastas compartilhadas</h2>

<p>Ontem também compartilhei uma pasta com a Jéssica (@jemmacedo), fiz isso rapidinho e sem dificuldades, o compartilhamento funcionou muito bem e continua funcionando.</p>

<h2>4. Armazenamento</h2>

<p>Outra questão interessante, quando você cria a conta já tem 15 Gigas de cara e chegará a 17 gigas fazendo um simples compartilhamento de link em alguma rede social. Você pode também fazer indicações de amigos, mas não é como o DROPBOX que pede acesso a sua conta do GMAIL e sai mandando convites a torto e direito, no COPY é um por um, você preenche nome, sobrenome e e-mail, contudo, cada pessoa que instalar te dá mais 5 GB de espaço enquanto o DROPBOX dá 500MB para a mesma coisa. No momento já estou com 32 GB de espaço por lá.</p>

<h2>5. Arquivos públicos</h2>

<p>Quando desejar compartilhar um arquivo de forma pública você pode escolher as redes sociais (Facebook, Twitter, Google Plus ou E-mail),
é gerado um LINK e este será postado nas redes sociais ou no e-mail.</p>

<p>Compartilhar por e-mail traz as mesmas vantagens do DROPBOX, vai o link apenas e não o arquivo anexo, evitando limitações de anexo e
deixando o coitado do administrador do servidor de e-mail mais feliz,
afinal e-mail não é para isto.</p>

<h2>6. Company</h2>

<p>Ele oferece ainda um recurso chamado <strong>company</strong>, que te permite criar um folder dentro do seu compartilhamento e definir usuários que podem utilizar esse folder, a versão free é bem simples mas existem planos pagos que habilitam mais recursos de controle, e não é cobrado por pessoa como em outros sistemas, é uma taxa única anual, mais simples e honesto - eu acho.</p>

<p>O que isso resolve?</p>

<p>Sabe quando você tem uma conta Dropbox pessoal e não quer misturar com a conta Dropbox de trabalho (é, tem muita gente que tem duas), pelo o que eu entendi o recurso company existe para resolver isto. Ao invés de ficar trocando de contas, o company trata isso de forma elegante - em minha humilde opinião, claro.</p>

<p>Mas isso não é igual a compartilhar uma pasta? Parecido, mas não é igual, afinal você tem mais recursos de controle, como grupos por exemplo, a versão &#8216;comercial&#8217; ainda oferece revogação de acesso
e além disto, o espaço <strong>company</strong> não usa seu espaço de usuário,
aparentemente é um storage separado.</p>

<h2>7. Plataformas suportadas</h2>

<ul>
<li>Linux</li>
<li>Windows</li>
<li>OSX</li>
<li>Android</li>
<li>IOS</li>
</ul>


<h2>8. Planos</h2>

<p>Eles tem dois tipos de planos, o pessoal e o company.</p>

<h3>8.1 Personal Plans</h3>

<ul>
<li>Free 15 GB => Sem custo e pode aumentar conforme indicações.</li>
<li>Pro 250 GB => U$ 9.9 dólares por mês ou U$ 99.00 por ano.</li>
<li>Pro 500 GB => U$ 14.99 dólares por mês ou U$ 149.00 por ano.</li>
</ul>


<h3>8.2 Company Plans</h3>

<ul>
<li>100 GB => U$ 399.00 por ano</li>
<li>250 GB => U$ 699.00 por ano</li>
<li>500 GB => U$ 999.00 por ano</li>
</ul>


<h3>8.3 Planos Copy vs Planos Dropbox</h3>

<p>Em relação aos planos PRO que são similares ao Personal do COPY</p>

<ul>
<li>DROPBOX FREE  => 2 GB</li>
<li>DROPBOX 100GB => U$ 9.99 por mês ou U$ 99 por ano</li>
<li>DROPBOX 200GB => U$ 19.99 por mês ou U$ 199 por ano</li>
<li>DROPBOX 500GB => U$ 49.99 por mês ou U$ 499 por ano</li>
</ul>


<p>O Dropbox tem planos para empresas mas depende da quantidade de usuários, é necessário solicitar um orçamento, contudo, segundo
o site do Dropbox, a partir de U$ 785,00 o uso de disco é ilimitado
mas não deixa claros se os usuários também.</p>

<h2>9. Screenshots</h2>

<h3>9.1 Web Interface</h3>

<p><img class="center" src="http://gutocarvalho.net/octopress/images/posts/2013-05-21/copy_web_interface_folders.png" title="[web interface folders]" ></p>

<p><img class="center" src="http://gutocarvalho.net/octopress/images/posts/2013-05-21/copy_web_interface_sharing.png" title="[web interface sharing]" ></p>

<p><img class="center" src="http://gutocarvalho.net/octopress/images/posts/2013-05-21/copy_web_company.png" title="[web interface company]" ></p>

<p><img class="center" src="http://gutocarvalho.net/octopress/images/posts/2013-05-21/copy_web_planos.png" title="[copy planos]" ></p>

<h3>9.2 OSX Interface</h3>

<p><img class="center" src="http://gutocarvalho.net/octopress/images/posts/2013-05-21/copy_osx_tela1.png" title="[copy osx tela 1]" ></p>

<p><img class="center" src="http://gutocarvalho.net/octopress/images/posts/2013-05-21/copy_osx_tela2.png" title="[copy osx tela 2]" ></p>

<p><img class="center" src="http://gutocarvalho.net/octopress/images/posts/2013-05-21/copy_osx_tela3.png" title="[copy osx tela 3]" ></p>

<p><img class="center" src="http://gutocarvalho.net/octopress/images/posts/2013-05-21/copy_osx_tela4.png" title="[copy osx tela 4]" ></p>

<p><img class="center" src="http://gutocarvalho.net/octopress/images/posts/2013-05-21/copy_osx_tela5.png" title="[copy osx tela 5]" ></p>

<h2>10. Amarrando as pontas</h2>

<p>Ainda é cedo para falar bem ou mal, mas estou gostando, o serviço promete, está estável e funcional, e parece que em breve se tornará viral, e isso será um desafio para a equipe que mantém a infra do serviço.</p>

<p>Vale lembrar que o serviço é novo, tem pouca gente usando em comparação com o DROPBOX, se saturar de usuários, poderá ficar igualmente lento, vamos aguardar e acompanhar a evolução do COPY.</p>

<h2>11. Referências</h2>

<ul>
<li><a href="https://www.copy.com">https://www.copy.com</a></li>
<li><a href="https://www.copy.com/about">https://www.copy.com/about</a></li>
<li><a href="https://www.copy.com/about/pr">https://www.copy.com/about/pr</a></li>
<li><a href="https://www.copy.com/developer">https://www.copy.com/developer</a></li>
<li><a href="https://www.copy.com/about/tos">https://www.copy.com/about/tos</a></li>
<li><a href="https://www.copy.com/about/dmca">https://www.copy.com/about/dmca</a></li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Dokuwiki atualizando versão]]></title>
    <link href="http://gutocarvalho.net/octopress/2013/05/20/dokuwiki-atualizando-versao/"/>
    <updated>2013-05-20T09:04:00-03:00</updated>
    <id>http://gutocarvalho.net/octopress/2013/05/20/dokuwiki-atualizando-versao</id>
    <content type="html"><![CDATA[<h2>1. Dokuwiki</h2>

<p>O dokuwiki é um sistema de blog que não usa banco de dados SQL, leve, simples e rápido, foi a minha escolha para aposentar o velho mediawiki.</p>

<p>Esse post é uma nota mental para me lembrar dos passos para atualizar o dokuwiki ;)</p>

<h2>2. Atualização do dokuwiki</h2>

<h3>2.1 Backup</h3>

<p>Faça o backup do seu dokuwiki.</p>

<pre><code>tar jcvf dokuwiki-AAAA-MM-DD.tar dokuwiki/
</code></pre>

<p>Pronto o backup completo está feito, e como não tem banco SQL, é só isso mesmo, está tudo em disco, arquivos texto.</p>

<h3>2.2 Download</h3>

<p>Faça o download da versão mais nova.</p>

<pre><code>wget http://www.splitbrain.org/_media/projects/dokuwiki/dokuwiki-2013-05-10.tgz
</code></pre>

<p>No momento deste post esta é a versão mais nova.</p>

<h3>2.3 Atualização</h3>

<p>Acesse o diretório do dokuwiki</p>

<pre><code>cd dokuwiki/
</code></pre>

<p>Atualize os arquivos</p>

<pre><code>tar -xzvf ../dokuwiki-2013-05-10.tgz --strip-components=1
</code></pre>

<p>Pronto, dokuwiki atualizado, essa foi rápida ;)</p>

<h3>2.4 Mensagem de upgrade</h3>

<p>Pode ser que ele continue mostrando que há atualização, mesmo após atualizar, então você tem duas opções, limpar o cache, aguardar 1 dia ou rodar um touch no arquivo doku.php, eu faço sempre a terceira.</p>

<pre><code>touch doku.php
</code></pre>

<p>E pronto, mensagem a de atualização sumiu.</p>

<h2>3. Referências</h2>

<ul>
<li>https://www.dokuwiki.org/changes</li>
<li>https://www.dokuwiki.org/install:upgrade</li>
<li>https://www.dokuwiki.org/install:unpacking</li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Octopress Table of Contents]]></title>
    <link href="http://gutocarvalho.net/octopress/2013/05/17/octopress-table-of-contents/"/>
    <updated>2013-05-17T16:30:00-03:00</updated>
    <id>http://gutocarvalho.net/octopress/2013/05/17/octopress-table-of-contents</id>
    <content type="html"><![CDATA[<p>Algumas pessoas tem me perguntado como eu criei a &#8220;Table of contents&#8221; em meus posts, eu simplesmente segui as orientações deste <a href="http://brizzled.clapper.org/blog/2012/02/04/generating-a-table-of-contents-in-octopress/">post</a>, em breve devo traduzir isto pra facilitar - aqui mesmo.</p>

<p>Este post é uma nota mental :)</p>

<p>[s]<br>
Guto</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[LVM dicas rápidas]]></title>
    <link href="http://gutocarvalho.net/octopress/2013/05/17/lvm-dicas-rapidas/"/>
    <updated>2013-05-17T10:36:00-03:00</updated>
    <id>http://gutocarvalho.net/octopress/2013/05/17/lvm-dicas-rapidas</id>
    <content type="html"><![CDATA[<h2>1. LVM</h2>

<p>LVM significa &#8220;Logic Volume Manager&#8221;, em português &#8220;Gerenciador de volume lógico&#8221;, ele gerencia discos e dispositivos de armazenamento em massa. No LVM um volume é o equivalente a uma partição de um disco.</p>

<h2>1.1 Usos do LVM</h2>

<p>O LVM é muito utilizado em servidores linux por oferecer uma capacidade de ajuste dinâmico de seus volumes.</p>

<p>Se você por exemplo que refazer o desenho de partições de um disco, no método tradicional você precisaria fazer backup dos dados, apagar as partições, criar um novo layout de partições, formatar as partições, reinstalar o sistema operacional e depois ainda fazer o restore dos dados, algo chato e demorado.</p>

<p>Se você utilizar LVM estará administrando seu armazenamento em uma camada de abstração, você trabalhará com volumes físicos (PV), grupos de volumes (VG) e volumes lógicos (LV), guarde esses nomes.</p>

<p>Quando você cria uma partição do disco destinada a uso via LVM esta partição será um PV (Physical Volume), e fará parte de algum VG (Volume Group), já os LV são &#8216;fatias&#8217; de algum VG.</p>

<p>Um VG pode ser criado com um ou mais PVs e o LVM lhe permite adicionar outros PVs a um VG para aumentar a capacidade de armazenamento quando for necessário.</p>

<p>Imagine um VG como se fosse um grande dispositivo de armazenamento composto por vários PVs, a capacidade total de armazenamento de um VG é a soma da capacidade dos PVs associados a ele.</p>

<p>LVs (Logical Volumes) são fatias do seu VG (volume group), imagine que você tem um VG com capacidade de 100 GB, você pode ter 10 LVs de 10GB ou dois LVs de 50GB, isso é configurável, para o sistema operacional linux, um LV equivale a uma partição de um disco, pode ser formatada e montada da mesma forma que uma partição de um disco comum.</p>

<p>A grande vantagem do LVM é que você pode redimensionar VGs e LVs, aumentando ou diminuindo seu tamanho, e se estiver utilizando um sistema de arquivos que suporte resize, algo como ext3 ou ext4, poderá também aumentar e diminuir o sistema de arquivos sem precisar reconstruir todas as partições e reinstalar seu ambiente.</p>

<h3>1.2 Vantagens</h3>

<p>Se o seu /var está quase cheio, e se você estiver utilizando LVM, bastará adicionar um novo PV (Physical Volume) ao VG (Volume Group) que possui o LV (Logical Volume) utilizado para o o ponto de montagem /VAR, após aumentar a capacidade do VG, você poderá com poucos comandos - em poucos minutos - aumentar o tamanho do /var sem grandes impactos em seu ambiente.</p>

<p>Especificamente para aumentar ou diminuir o /var, será necessário parar a máquina, mas dependendo da partição não será preciso.</p>

<p>Você pode também diminuir um LV que não esteja usando muito espaço para aumentar outro que esteja precisando de espaço, desde que estejam no mesmo VG.</p>

<p>O LVM torna a administração de partições algo muito flexível.</p>

<h3>1.3 Desvantagens</h3>

<p>Um VG é composto por PVs, se um PV quebrar você perde o VG e os LVs, isso pode ser um grande problema, portanto, é importante ter confiança nos discos envolvidos em um ambiente LVM.</p>

<p>Se possível é interessante utilizar RAID para poder perder um ou mais discos de um LVM sem perder seu VG inteiro.</p>

<p>Há quem diga também que por ser uma camada a mais em seu ambiente, haverá perda de performance em relação a gravação e leitura em um PV, contudo, acho que isso é imperceptível na grande maioria dos ambientes.</p>

<p>Normalmente o LVM versão 2 já vem instalado na maioria das distribuições linux, em Debian e CentOS está disponível desde a instalação.</p>

<h2>2. Mão na massa</h2>

<p>Vamos aprender a trabalhar com LVM, no estilo dicas rápidas.</p>

<h3>2.1 Criando partição LVM</h3>

<p>Vamos particionar o disco sdb como exemplo</p>

<pre><code>fdisk /dev/sdb
</code></pre>

<p>Acesse a ajuda</p>

<pre><code>Command (m for help): m
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Command action
</span><span class='line'>   a   toggle a bootable flag
</span><span class='line'>   b   edit bsd disklabel
</span><span class='line'>   c   toggle the dos compatibility flag
</span><span class='line'>   d   delete a partition
</span><span class='line'>   l   list known partition types
</span><span class='line'>   m   print this menu
</span><span class='line'>   n   add a new partition
</span><span class='line'>   o   create a new empty DOS partition table
</span><span class='line'>   p   print the partition table
</span><span class='line'>   q   quit without saving changes
</span><span class='line'>   s   create a new empty Sun disklabel
</span><span class='line'>   t   change a partition's system id
</span><span class='line'>   u   change display/entry units
</span><span class='line'>   v   verify the partition table
</span><span class='line'>   w   write table to disk and exit
</span><span class='line'>   x   extra functionality (experts only)</span></code></pre></td></tr></table></div></figure>


<p>Vamos criar uma nova partição</p>

<pre><code>Command (m for help): n
</code></pre>

<p>Escolha o tipo de partição</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Partition type:
</span><span class='line'>   p   primary (0 primary, 0 extended, 4 free)
</span><span class='line'>   e   extended
</span></code></pre></td></tr></table></div></figure>


<p>Eu escolhi primária, as quatro primeiras partições de um disco podem ser primárias, se você pretende ter mais de quatro partições, crie 3 primárias e uma extendida.</p>

<pre><code>Select (default p): p
</code></pre>

<p>Esta será a primeira partição</p>

<pre><code>Partition number (1-4, default 1): 1
</code></pre>

<p>Agora o fdisk me pergunta em qual setor essa partição deve começar e depois ele também pergunta o tamanho, eu vou dar ENTER e depois ENTER para usar todo o disco a partir do primeiro setor.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>First sector (2048-125829119, default 2048):
</span><span class='line'>Using default value 2048
</span><span class='line'>Last sector, +sectors or +size{K,M,G} (2048-125829119, default 125829119):
</span><span class='line'>Using default value 125829119</span></code></pre></td></tr></table></div></figure>


<p>Agora vou imprimir as partições</p>

<pre><code>Command (m for help): p
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Disk /dev/sdb: 64.4 GB, 64424509440 bytes
</span><span class='line'>255 heads, 63 sectors/track, 7832 cylinders, total 125829120 sectors
</span><span class='line'>Units = sectors of 1 * 512 = 512 bytes
</span><span class='line'>Sector size (logical/physical): 512 bytes / 512 bytes
</span><span class='line'>I/O size (minimum/optimal): 512 bytes / 512 bytes
</span><span class='line'>Disk identifier: 0xe61fc21b
</span><span class='line'>
</span><span class='line'>   Device Boot      Start         End      Blocks   Id  System
</span><span class='line'>/dev/sdb1            2048   125829119    62913536   83  Linux</span></code></pre></td></tr></table></div></figure>


<p>Veja que uma partição foi criada, agora vamos definir o tipo da partição, veja os tipos disponíveis</p>

<pre><code>command (m for help): l
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
</pre></td><td class='code'><pre><code class=''><span class='line'> 0  Empty           24  NEC DOS         81  Minix / old Lin bf  Solaris
</span><span class='line'> 1  FAT12           27  Hidden NTFS Win 82  Linux swap / So c1  DRDOS/sec (FAT-
</span><span class='line'> 2  XENIX root      39  Plan 9          83  Linux           c4  DRDOS/sec (FAT-
</span><span class='line'> 3  XENIX usr       3c  PartitionMagic  84  OS/2 hidden C:  c6  DRDOS/sec (FAT-
</span><span class='line'> 4  FAT16 &lt;32M      40  Venix 80286     85  Linux extended  c7  Syrinx
</span><span class='line'> 5  Extended        41  PPC PReP Boot   86  NTFS volume set da  Non-FS data
</span><span class='line'> 6  FAT16           42  SFS             87  NTFS volume set db  CP/M / CTOS / .
</span><span class='line'> 7  HPFS/NTFS/exFAT 4d  QNX4.x          88  Linux plaintext de  Dell Utility
</span><span class='line'> 8  AIX             4e  QNX4.x 2nd part 8e  Linux LVM       df  BootIt
</span><span class='line'> 9  AIX bootable    4f  QNX4.x 3rd part 93  Amoeba          e1  DOS access
</span><span class='line'> a  OS/2 Boot Manag 50  OnTrack DM      94  Amoeba BBT      e3  DOS R/O
</span><span class='line'> b  W95 FAT32       51  OnTrack DM6 Aux 9f  BSD/OS          e4  SpeedStor
</span><span class='line'> c  W95 FAT32 (LBA) 52  CP/M            a0  IBM Thinkpad hi eb  BeOS fs
</span><span class='line'> e  W95 FAT16 (LBA) 53  OnTrack DM6 Aux a5  FreeBSD         ee  GPT
</span><span class='line'> f  W95 Ext'd (LBA) 54  OnTrackDM6      a6  OpenBSD         ef  EFI (FAT-12/16/
</span><span class='line'>10  OPUS            55  EZ-Drive        a7  NeXTSTEP        f0  Linux/PA-RISC b
</span><span class='line'>11  Hidden FAT12    56  Golden Bow      a8  Darwin UFS      f1  SpeedStor
</span><span class='line'>12  Compaq diagnost 5c  Priam Edisk     a9  NetBSD          f4  SpeedStor
</span><span class='line'>14  Hidden FAT16 &lt;3 61  SpeedStor       ab  Darwin boot     f2  DOS secondary
</span><span class='line'>16  Hidden FAT16    63  GNU HURD or Sys af  HFS / HFS+      fb  VMware VMFS
</span><span class='line'>17  Hidden HPFS/NTF 64  Novell Netware  b7  BSDI fs         fc  VMware aMKCORE
</span><span class='line'>18  AST SmartSleep  65  Novell Netware  b8  BSDI swap       fd  Linux raid auto
</span><span class='line'>1b  Hidden W95 FAT3 70  DiskSecure Mult bb  Boot Wizard hid fe  LANstep
</span><span class='line'>1c  Hidden W95 FAT3 75  PC/IX           be  Solaris boot    ff  BBT
</span><span class='line'>1e  Hidden W95 FAT1 80  Old Minix</span></code></pre></td></tr></table></div></figure>


<p>Agora vamos definir o tipo da partição</p>

<pre><code>Command (m for help): t
</code></pre>

<p>Escolha LVM (tipo 8e)</p>

<pre><code>Selected partition 1
Hex code (type L to list codes): 8e
Changed system type of partition 1 to 8e (Linux LVM)
</code></pre>

<p>Vamos imprimir novamente a tabela de partições do disco</p>

<pre><code>command (m for help): p
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Disk /dev/sdb: 64.4 GB, 64424509440 bytes
</span><span class='line'>255 heads, 63 sectors/track, 7832 cylinders, total 125829120 sectors
</span><span class='line'>Units = sectors of 1 * 512 = 512 bytes
</span><span class='line'>Sector size (logical/physical): 512 bytes / 512 bytes
</span><span class='line'>I/O size (minimum/optimal): 512 bytes / 512 bytes
</span><span class='line'>Disk identifier: 0xe61fc21b
</span><span class='line'>
</span><span class='line'>   Device Boot      Start         End      Blocks   Id  System
</span><span class='line'>/dev/sdb1            2048   125829119    62913536   8e  Linux LVM</span></code></pre></td></tr></table></div></figure>


<p>Ótimo, tudo certo, agora vamos gravar essa configuração no disco</p>

<pre><code>Command (m for help): w
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>The partition table has been altered!
</span><span class='line'>
</span><span class='line'>Calling ioctl() to re-read partition table.
</span><span class='line'>Syncing disks.</span></code></pre></td></tr></table></div></figure>


<p>Agora já podemos sair do fdisk</p>

<pre><code>Command (m for help): q
</code></pre>

<p>Pronto, para ter certeza que está tudo certo rode o comando abaixo</p>

<pre><code>fdisk -l /dev/sdb
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Disk /dev/sdb: 64.4 GB, 64424509440 bytes
</span><span class='line'>128 heads, 39 sectors/track, 25206 cylinders, total 125829120 sectors
</span><span class='line'>Units = sectors of 1 * 512 = 512 bytes
</span><span class='line'>Sector size (logical/physical): 512 bytes / 512 bytes
</span><span class='line'>I/O size (minimum/optimal): 512 bytes / 512 bytes
</span><span class='line'>Disk identifier: 0xe61fc21b
</span><span class='line'>
</span><span class='line'>   Device Boot      Start         End      Blocks   Id  System
</span><span class='line'>/dev/sdb1            2048   125829119    62913536   8e  Linux LVM</span></code></pre></td></tr></table></div></figure>


<p>Veja que a partição sdb1 foi criada corretamente</p>

<h3>2.2 Criando PV</h3>

<p>Agora que já temos uma partição LVM, podemos criar um volume físico (PV)</p>

<pre><code>pvcreate /dev/sdb1
</code></pre>

<p>Vamos checar os PVs</p>

<pre><code>pvscan
</code></pre>

<p>Veja detalhes dos PVs</p>

<pre><code>pvdisplay
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>"/dev/sdb1" is a new physical volume of "60.00 GiB"
</span><span class='line'>  --- NEW Physical volume ---
</span><span class='line'>  PV Name               /dev/sdb1
</span><span class='line'>  VG Name
</span><span class='line'>  PV Size               60.00 GiB
</span><span class='line'>  Allocatable           NO
</span><span class='line'>  PE Size               0
</span><span class='line'>  Total PE              0
</span><span class='line'>  Free PE               0
</span><span class='line'>  Allocated PE          0
</span><span class='line'>  PV UUID               KtmCte-RHtK-XgTi-rLnd-qGL0-0OZe-8KHm4b</span></code></pre></td></tr></table></div></figure>


<p>Beleza, agora podemos criar um VG</p>

<h3>2.3 Criando VG</h3>

<p>Depois de criar os volumes físicos, podemos criar os grupos de volume</p>

<pre><code>vgcreate fileserver /dev/sdb1
</code></pre>

<p>Verifique os VGs existentes</p>

<pre><code>vgscan
</code></pre>

<p>Veja detalhes dos VGs</p>

<pre><code>vgdisplay
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>--- Volume group ---
</span><span class='line'>  VG Name               fileserver
</span><span class='line'>  System ID
</span><span class='line'>  Format                lvm2
</span><span class='line'>  Metadata Areas        1
</span><span class='line'>  Metadata Sequence No  1
</span><span class='line'>  VG Access             read/write
</span><span class='line'>  VG Status             resizable
</span><span class='line'>  MAX LV                0
</span><span class='line'>  Cur LV                0
</span><span class='line'>  Open LV               0
</span><span class='line'>  Max PV                0
</span><span class='line'>  Cur PV                1
</span><span class='line'>  Act PV                1
</span><span class='line'>  VG Size               60.00 GiB
</span><span class='line'>  PE Size               4.00 MiB
</span><span class='line'>  Total PE              15359
</span><span class='line'>  Alloc PE / Size       0 / 0
</span><span class='line'>  Free  PE / Size       15359 / 60.00 GiB
</span><span class='line'>  VG UUID               JYkvTQ-hZ3R-Mib0-tIzm-CXmr-7NWH-UPu8UT</span></code></pre></td></tr></table></div></figure>


<h3>2.4 Adicionando PV a VG</h3>

<p>Se você quer expandir o seu VG adicionando outra partição use o comando abaixo</p>

<pre><code>vgextend fileserver /dev/sdc1
</code></pre>

<h3>2.5 Criando LV</h3>

<p>Agora que temos um grupo de volumes, vamos criar um volume lógico</p>

<pre><code>lvcreate --name public --size 40G fileserver
</code></pre>

<p>Verique os LVs</p>

<pre><code>lvscan
</code></pre>

<p>Veja detalhes dos LVs</p>

<pre><code>lvdisplay
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>  --- Logical volume ---
</span><span class='line'>  LV Path                /dev/fileserver/fileserver-public
</span><span class='line'>  LV Name                public
</span><span class='line'>  VG Name                fileserver
</span><span class='line'>  LV UUID                Qn8u3P-Olgx-whQE-eLPn-OiaH-eguo-jfM8Vg
</span><span class='line'>  LV Write Access        read/write
</span><span class='line'>  LV Creation host, time debian64, 2013-05-16 11:51:59 -0300
</span><span class='line'>  LV Status              available
</span><span class='line'>  # open                 1
</span><span class='line'>  LV Size                40.00 GiB
</span><span class='line'>  Current LE             39424
</span><span class='line'>  Segments               2
</span><span class='line'>  Allocation             inherit
</span><span class='line'>  Read ahead sectors     auto
</span><span class='line'>  - currently set to     256
</span><span class='line'>  Block device           254:2</span></code></pre></td></tr></table></div></figure>


<p></p>

<h3>2.6 Formatando a partição</h3>

<p>Depois de criar o LV já podemos formatá-lo</p>

<pre><code>mkfs.ext4 /dev/mapper/fileserver-public
</code></pre>

<h3>2.7 Montando a partição</h3>

<pre><code>mkdir /srv/public
mount /dev/mapper/fileserver-public /srv/public   
</code></pre>

<h3>2.8 Configurando fstab</h3>

<p>Verifique o identificador único das partições</p>

<pre><code>blkid /dev/sdb1
</code></pre>

<p>Acompanhe a saída</p>

<pre><code>/dev/mapper/fileserver-public: UUID="811782cc-ddc3-43ca-8ba8-f67efa80f229" TYPE="ext4"     
</code></pre>

<p>No fstab insira a seguinte linha</p>

<pre><code>UUID=811782cc-ddc3-43ca-8ba8-f67efa80f229 /srv/public               ext4    defaults 0       1
</code></pre>

<h3>2.9 Aumentando LV (ext4)</h3>

<p>Desmonte a partição</p>

<pre><code>umount /srv/public
</code></pre>

<p>Vamos estender o volume lógico adicionando mais 114 GB ao LV</p>

<pre><code>lvextend -L +114GB /dev/mapper/fileserver-public
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Extending logical volume fileserver to 154.00 GiB
</span><span class='line'>Logical volume mirrordata successfully resized </span></code></pre></td></tr></table></div></figure>


<p>E depois vamos passar o e2fsck para o verificar o LV</p>

<pre><code>e2fsck -f /dev/mapper/fileserver-public 
</code></pre>

<p>Agora vamos aumentar a partição ext4</p>

<pre><code>resize2fs -p /dev/mapper/fileserver-public
</code></pre>

<p>Rode novamente o e2fsck para checar a partição que fora estendida</p>

<pre><code>e2fsck -f /dev/mapper/fileserver-public
</code></pre>

<p>Monte a nova partição</p>

<pre><code>mount /srv/public
</code></pre>

<p>Pronto, partição estendida.</p>

<h3>2.10 Diminuindo LV (ext4)</h3>

<p>Desmonte o filesystem</p>

<pre><code>umount /srv/public
</code></pre>

<p>Antes de prosseguir verifique a partição</p>

<pre><code>e2fsck -f /dev/mapper/fileserver-public
</code></pre>

<p>Diminua o LV em 40GB</p>

<pre><code>resize2fs -p /dev/mapper/fileserver-public 40G
</code></pre>

<p>Diminua a partição ext4 em 40 gigas</p>

<pre><code>lvreduce -L 40G /dev/mapper/fileserver-public
</code></pre>

<p>Verifique a partição</p>

<pre><code>e2fsck -f /dev/mapper/fileserver-public
</code></pre>

<p>Rode mais uma vez o o resize para se certificar que partição vai ficar do mesmo tamanho do LV</p>

<pre><code>resize2fs -p /dev/mapper/fileserver-public
</code></pre>

<p>Verifique a partição</p>

<pre><code>e2fsck -f /dev/mapper/fileserver-public
</code></pre>

<p>Monte a partição</p>

<pre><code>mount /srv/public
</code></pre>

<p>Pronto.</p>

<h2>3. Referências</h2>

<ul>
<li><p><a href="http://www.tldp.org/HOWTO/LVM-HOWTO/">http://www.tldp.org/HOWTO/LVM-HOWTO/</a></p></li>
<li><p><a href="http://sourceware.org/lvm2/">http://sourceware.org/lvm2/</a></p></li>
<li><p><a href="http://en.wikipedia.org/wiki/Logical_Volume_Manager_(Linux">http://en.wikipedia.org/wiki/Logical_Volume_Manager_(Linux)</a>)</p></li>
<li><p><a href="http://pubmem.wordpress.com/2010/09/16/how-to-resize-lvm-logical-volumes-with-ext4-as-filesystem/">http://pubmem.wordpress.com/2010/09/16/how-to-resize-lvm-logical-volumes-with-ext4-as-filesystem/</a></p></li>
<li><p><a href="http://www.howtoforge.com/linux_lvm_p2">http://www.howtoforge.com/linux_lvm_p2</a></p></li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Octopress feeds por categoria]]></title>
    <link href="http://gutocarvalho.net/octopress/2013/05/15/octopress-feeds-por-categoria/"/>
    <updated>2013-05-15T17:10:00-03:00</updated>
    <id>http://gutocarvalho.net/octopress/2013/05/15/octopress-feeds-por-categoria</id>
    <content type="html"><![CDATA[<p>Hoje eu precisei aprender a habilitar feeds xml por categoria em meu octopress, esse procedimento é simples, o recurso é nativo, contudo, vem desabilitado.</p>

<p>Primeiro acesse o feed principal e veja que o arquivo chama-se atom.xml</p>

<pre><code>http://gutocarvalho/octopress/atom.xml
</code></pre>

<p>Agora ative o feed de categorias no arquivo _config.yml</p>

<pre><code>category_feeds: true
</code></pre>

<p>E depois rode um generate e deploy</p>

<pre><code>rake generate &amp;&amp; rake deploy
</code></pre>

<p>A partir daí basta entrar na página de uma categoria</p>

<pre><code>http://gutocarvalho.net/octopress/categories/puppet
</code></pre>

<p>Neste mesmo diretório teremos um arquivo chamado atom.xml, acesse o arquivo para visualizar o feed XML.</p>

<pre><code>http://gutocarvalho.net/octopress/categories/puppet/atom.xml
</code></pre>

<p>Simples, rápido e sem gambiarras.</p>

<p>[s]<br>
Guto</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Instalando Zabbix 2 no Debian com pacotes oficiais Zabbix]]></title>
    <link href="http://gutocarvalho.net/octopress/2013/05/08/instalando-zabbix-2-no-debian-com-pacotes-oficiais-zabbix/"/>
    <updated>2013-05-08T11:38:00-03:00</updated>
    <id>http://gutocarvalho.net/octopress/2013/05/08/instalando-zabbix-2-no-debian-com-pacotes-oficiais-zabbix</id>
    <content type="html"><![CDATA[<p>Neste <a href="http://gutocarvalho.net/octopress/2013/01/14/instalando-zabbix-2x-em-debian-squeeze">post</a> eu já mostrei como instalar o zabbix 2 compilando, agora
vou mostrar como instalar o zabbix 2 utilizando os pacotes oficiais da zabbix.org para debian.</p>

<h2>1. Instalando chave</h2>

<h3>1.1 Adicionando chave manualmente</h3>

<p>Faça o download da chave e adicionei ao seu chaveiro.</p>

<pre><code>wget http://repo.zabbix.com/zabbix-official-repo.key -O - | apt-key add -
</code></pre>

<h3>1.2 Adicionando chave via pacote</h3>

<p>Faça o download do pacote release</p>

<pre><code>wget http://repo.zabbix.com/zabbix/2.0/debian/pool/main/z/zabbix-release/zabbix-release_2.0-1squeeze_all.deb
</code></pre>

<p>Instale o pacote</p>

<pre><code>dpkg -i zabbix-release_2.0-1squeeze_all.deb
</code></pre>

<p>Esse pacote além de instalar a chave, já adiciona o repositório, portato se optar por ele, pule o passo 2.</p>

<h2>2. Configurando repositório</h2>

<p>Adicione a linha abaixo ao sources.list do seu squeeze</p>

<pre><code>deb http://repo.zabbix.com/zabbix/2.0/debian squeeze main
</code></pre>

<p>Atualize os índices de pacotes</p>

<pre><code>aptitude update
</code></pre>

<p>Pronto, já é possível encontrar os pacotes em uma pesquisa</p>

<pre><code>aptitude search zabbix
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>p   zabbix-agent                                      - network monitoring solution - agent
</span><span class='line'>p   zabbix-frontend-php                               - network monitoring solution - PHP front-end
</span><span class='line'>p   zabbix-get                                        - network monitoring solution - get
</span><span class='line'>p   zabbix-java-gateway                               - network monitoring solution - java-gateway
</span><span class='line'>p   zabbix-proxy-mysql                                - network monitoring solution - proxy (using MySQL)
</span><span class='line'>p   zabbix-proxy-pgsql                                - network monitoring solution - proxy (using PostgreSQL)
</span><span class='line'>p   zabbix-proxy-sqlite3                              - network monitoring solution - proxy (using SQLite3)
</span><span class='line'>p   zabbix-release                                    - Zabbix official repository configuration
</span><span class='line'>p   zabbix-sender                                     - network monitoring solution - sender
</span><span class='line'>p   zabbix-server-mysql                               - network monitoring solution - server (using MySQL)
</span><span class='line'>p   zabbix-server-pgsql                               - network monitoring solution - server (using PostgreSQL)</span></code></pre></td></tr></table></div></figure>


<p>E podemos verificar a versão</p>

<pre><code>aptitude show zabbix-agent|grep ^Version
</code></pre>

<p>Acompanhe a saída</p>

<pre><code>Version: 1:2.0.6-1
</code></pre>

<p>Pacotes na última versão</p>

<h2>3. Instalando o Zabbix Server</h2>

<p>Acompanhe duas formas de instalar o zabbix-server</p>

<h3>3.1 Zabbix Server com backend pgsql</h3>

<p>Instalando o zabbix server com banco de dados postgresql</p>

<pre><code>aptitude install zabbix-server-pgsql
</code></pre>

<h3>3.1 Zabbix Server com Backend mysql</h3>

<p>Instalando o zabbix server com banco de dados mysql</p>

<pre><code>aptitude install zabbix-server-mysql
</code></pre>

<h2>4. Instalando Zabbix Agent</h2>

<p>Instalando o agente de monitoramento do zabbix</p>

<pre><code>aptitude install zabbix-agent
</code></pre>

<h2>5. Instalando Zabbix Java Gateway</h2>

<p>Instalando o gateway de monitoramento de aplicações JAVA e máquina virtual java.</p>

<pre><code>aptitude install zabbix-java-gateway
</code></pre>

<h2>6. Instalando Zabbix Proxy</h2>

<p>Acompanhe 3 formas de instalar o Zabbix Proxy.</p>

<h2>6.1 Proxy com backend mysql</h2>

<p>Instalando zabbix proxy com banco de dados mysql</p>

<pre><code>aptitude install zabbix-proxy-mysql
</code></pre>

<h2>6.2 Proxy com backend pgsql</h2>

<p>Instalando zabbix proxy com banco de dados pgsql</p>

<pre><code>aptitude install zabbix-proxy-pgsql
</code></pre>

<h2>6.3 Proxy com backend sqlite3</h2>

<p>Instalando zabbix proxy com banco de dados sqlite3</p>

<pre><code>aptitude install zabbix-proxy-sqlite3
</code></pre>

<h2>7.Instalando Frontend PHP</h2>

<p>Instalando frontend web para configuração e visualização de dados de monitoramento</p>

<pre><code>aptitude install zabbix-frontend-php
</code></pre>

<h2>8. Instalando Get &amp; Sender</h2>

<p>Instalando ferramentas de consulta ao agente (get) e envio de dados (sender) ao servidor.</p>

<pre><code>aptitude install zabbix-get
aptitude install zabbix-sender
</code></pre>

<p>Utilizar pacotes facilita e muito a administração de seu ambiente, principalmente
em caso de atualização, usar os pacotes mantidos pela zabbix.org é certeza de ter
sempre as últimas versões do Zabbix empacotadas.</p>

<p>Se precisa de agilidade use os pacotes/binários, não pense duas vezes.</p>

<p>[s]
Guto</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Octopress com aside de comentários recentes]]></title>
    <link href="http://gutocarvalho.net/octopress/2013/04/25/octopress-disqus-recent-comment-aside/"/>
    <updated>2013-04-25T13:35:00-03:00</updated>
    <id>http://gutocarvalho.net/octopress/2013/04/25/octopress-disqus-recent-comment-aside</id>
    <content type="html"><![CDATA[<p>Pesquisando sobre aside (widget) para o disqus no octopress, encontrei um post no site <a href="http://arshad.github.io/blog/2012/05/04/recent-comments-in-octopress/">arshad</a> que explica como fazer isto em poucos passos, vamos para a explicação.</p>

<h2>1. Criando aside</h2>

<p>Vamos criar um arquivo chamado <strong>recent_comment.html</strong> dentro de /caminho/para/octopress/source/_includes/custom/asides</p>

<pre><code>touch /path/to/octopress/source/_includes/custom/asides/recent_comment.html
</code></pre>

<h2>2. Adicionando código ao arquivo</h2>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>&lt;section&gt;
</span><span class='line'>  &lt;h1&gt;Recent Comments&lt;/h1&gt;
</span><span class='line'>  &lt;div id="dsq-recentcomments" class="dsq-widget"&gt;&lt;script type="text/javascript" src="http://disqus.com/forums/gutocarvalho/recent_comments_widget.js?hide_avatars=1;num_items=4"&gt;&lt;/script&gt;&lt;/div&gt;
</span><span class='line'>&lt;/section&gt;</span></code></pre></td></tr></table></div></figure>


<h3>2.1 Sobre os parâmetros disponíveis</h3>

<p>Para esconder avatar</p>

<pre><code>hide_avatars=0 (values : 0 show, 1 hide)
</code></pre>

<p>Quantidade de comentários a serem mostrados</p>

<pre><code>num_items=4
</code></pre>

<p>Tamanho máximo de caracteres por comentários</p>

<pre><code>xcerpt_length=140
</code></pre>

<h2>3. Adicione o aside ao _config.yml</h2>

<p>Procure o parâmetro default asides e insira após recent_posts.html</p>

<pre><code>custom/asides/recent_comment.html
</code></pre>

<p>Após o ajuste a configuração do parâmetro ficará desse jeito</p>

<pre><code>default_asides: [custom/asides/links.html, asides/recent_posts.html, custom/asides/recent_comment.html, asides/github.html, asides/twitter.html, asides/delicious.html, asides/pinboard.html, asides/googleplus.html]
</code></pre>

<h2>4. Faça o rebuild do seu site</h2>

<p>Agora basta fazer o rebuild</p>

<pre><code>rake generate &amp;&amp; rake deploy
</code></pre>

<p>Após finalizar o comando, você verá o aside funcionando, simples assim.</p>

<p>[s]<br>
Guto</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[FLISOL 2013 BR/DF]]></title>
    <link href="http://gutocarvalho.net/octopress/2013/04/24/flisol-2013-df/"/>
    <updated>2013-04-24T07:01:00-03:00</updated>
    <id>http://gutocarvalho.net/octopress/2013/04/24/flisol-2013-df</id>
    <content type="html"><![CDATA[<h2>1. O que é o FLISOL?</h2>

<p><img class="right" src="http://gutocarvalho.net/octopress/images/logo_flisol.png"></p>

<p>O Festival Latino Americano de Instalação de Software Livre – FLISol é um evento internacional, realizado anualmente, e que ocorre de forma simultânea em diversas cidades da América Latina. O Flisol é um evento descentralizado, onde diversas comunidades organizam e realizam seu festival, de forma voluntária, tendo como principal objetivo promover o uso de software livre, apresentando sua filosofia, alcance, avanços e desenvolvimento ao público em geral.</p>

<p>O Flisol acontece, historicamente, no 4º sábado de abril (em 2006 foi no 25 de março; em 2007, 28 de abril; 2008, 26 de abril; 2009 e 2010, no dia 24 de abril; 2011, no dia 9 de abril; 2012, no dia 28 de abril). O Flisol 2013 está marcado para o dia 27 de abril.</p>

<p>O evento é gratuito e aberto a todo o público: curiosos, interessados e amantes do Software Livre. Nesse dia os voluntários propõe a instalação de Software Livre, como distribuições de Gnu/Linux, sistemas BSD, e aplicativos livres para Windows em geral. Alguns eventos também contam com palestras, oficinas, sala de degustação e gravações de mídias (live-CD/DVD e/ou pendrives).</p>

<h3>1.1. FLISOL-DF</h3>

<p>A cada ano a organização do FLISOL no Distrito Federal escolhe um local diferente para realização do evento, neste ano o evento será no IESB OESTE – Ceilândia Norte, QNN 31 – Áreas Especiais B/C/D/E, Ceilândia – DF.</p>

<p>Mais detalhes no site <a href="http://www.flisoldf.blog.br">http://www.flisoldf.blog.br</a>.</p>

<h3>1.2. Lista de atividades</h3>

<p>Acesse a <a href="http://sistema.flisoldf.blog.br/public/atividades">lista de atividades</a> do evento e faça sua inscrição nas palestras e oficinas em que deseje participar.</p>

<h2>2. Minhas atividades no FLISOL-DF</h2>

<p>Eu vou apresentar quatro trabalhos no FLISOL deste ano, veja os detalhes a seguir.</p>

<h3>2.1. Monitoramento avançado com Zabbix 2.0</h3>

<p>Horário: 11:00hs</p>

<p>Sala: Espaço Ubuntu - Sala BA11 - Bloco B</p>

<p>A palestra tem o objetivo de apresentar a ferramenta de monitoração Zabbix e os seus principais recursos na versão 2.0. A atividade abordará conceitos de monitoramento, fará uma introducão ao zabbix e apresentará os seus recursos comuns. Em um segundo momento demonstrará os novos recursos do zabbix 2.0 como: zabbix distribuído (proxy/node), zabbix monitorando aplicações java com JMX Gateway e tuning de Zabbix para grandes ambientes.</p>

<h3>2.2. Oficina de instalação de Zabbix 2.0</h3>

<p>Horário: 14:00hs</p>

<p>Sala: Espaço Mandriva - Sala BA5 - Bloco B</p>

<p>Oficina de instalação do Zabbix Server, Zabbix Frontend, Zabbix Agent, Zabbix Proxy e JMX Gateway.</p>

<h2>2.3. Infraestrutura ágil</h2>

<p>Horário: 15:00hs</p>

<p>Sala: Espaço Fedora - Sala BA6 - Bloco B</p>

<p>Apresentar o conceito de gerência de configurações, orquestração e provisionamento utilizando as ferramentas Puppet e Mcollective. Demonstrar que com o uso destas tecnologias o administrador de sistemas terá condições de administrar centenas de servidores de forma descomplicada, centraliza e ágil. Dentre as principais vantagens no uso de gerência de configurações estão: Diminuição de custos, Diminuição de incidentes, Padronização do ambiente, Diminui o tempo gasto com mudanças, Controle e acompanhamento do ciclo de vida do parque de servidores.</p>

<h2>2.4. O que é DevOps afinal?</h2>

<p>Horário: 16:00hs</p>

<p>Sala: Espaço Puppy - Sala AA1 - Bloco A</p>

<p>O objetivo é esclarecer de forma objetiva o que significa DevOps, mostrar como esse movimento se iniciou, apresentar suas principais características e indicar um caminho para que se consiga absorver e internalizar essa cultura no ambiente corporativo. DevOps é essencialmente uma cultura que busca entregar sistemas melhores, com menor custo, fazendo isto de forma mais rápida e com menor risco. Dentro de DevOps trabalhamos intensamente automação, principalmente automação de infraestrutura com gerência de configurações, orquestração e provisionamento, falaremos muito de infraestrutura como código.</p>

<p>Nos vemos no FLISOL.</p>

<p>[s]<br>
Guto</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Puppet Melhores Práticas]]></title>
    <link href="http://gutocarvalho.net/octopress/2013/04/22/puppet-melhores-praticas/"/>
    <updated>2013-04-22T13:35:00-03:00</updated>
    <id>http://gutocarvalho.net/octopress/2013/04/22/puppet-melhores-praticas</id>
    <content type="html"><![CDATA[<h2>1. Melhores Práticas</h2>

<p>Neste post vou agrupar algumas dicas aprendidas no dia-a-dia em produção, são dicas que me ajudaram, espero que lhe seja útil também.</p>

<h2>2. Organizando o site.pp</h2>

<p>Evite deixar o arquivo site.pp lotado de código, use o recurso <strong>import</strong>, separe as configurações em arquivos para ficar mais organizado.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="c-Singleline"># /etc/puppet/manifests/site.pp</span>
</span><span class='line'><span class="c-Singleline">  </span>
</span><span class='line'><span class="c-Singleline"># importando manifests em diretórios</span>
</span><span class='line'>
</span><span class='line'><span class="kn">import</span> <span class="s2">&quot;nodes/*.pp&quot;</span><span class="c-Singleline">      # importando manifest com declaração de nodes</span>
</span><span class='line'><span class="s">import</span> <span class="s2">&quot;classes/*.pp&quot;</span><span class="c-Singleline">    # importando classes simples</span>
</span><span class='line'>
</span><span class='line'><span class="c-Singleline"># importando manifests</span>
</span><span class='line'>
</span><span class='line'><span class="kn">import</span> <span class="s2">&quot;filebucket.pp&quot;</span><span class="c-Singleline">   # importando configurações do filebucket</span>
</span><span class='line'><span class="s">import</span> <span class="s2">&quot;providers.pp&quot;</span><span class="c-Singleline">    # importando configurações globais de providers</span>
</span><span class='line'><span class="s">import</span> <span class="s2">&quot;globals.pp&quot;</span><span class="c-Singleline">      # importando configuraçoes globais variadas</span>
</span><span class='line'><span class="s">import</span> <span class="s2">&quot;extdata.pp&quot;</span><span class="c-Singleline">      # importando configurações de extlookup</span>
</span></code></pre></td></tr></table></div></figure>


<p>Sempre que houver alguma alteração em um manifest importado no site.pp, será necessário reiniciar o puppetmaster ou apache (se estiver usando passenger).</p>

<h3>1.1 Arquivo filebucket.pp:</h3>

<p>Neste arquivo eu normalmente insiro configurações do filebucket.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="c-Singleline"># Define the bucket</span>
</span><span class='line'><span class="nc">filebucket</span> <span class="p">{</span> <span class="s1">&#39;main&#39;</span><span class="p">:</span>
</span><span class='line'>  <span class="nt">server</span> <span class="p">=&gt;</span> <span class="ss">puppet</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">path</span>   <span class="p">=&gt;</span> <span class="ss">false</span><span class="p">,</span>
</span><span class='line'>  <span class="c-Singleline"># Due to a known issue, path must be set to false for remote filebuckets.</span>
</span><span class='line'><span class="p">}</span><span class="c-Singleline"></span>
</span><span class='line'>
</span><span class='line'><span class="c-Singleline"># Specify it as the default target</span>
</span><span class='line'><span class="nc">File</span> <span class="p">{</span> <span class="nt">backup</span> <span class="p">=&gt;</span> <span class="ss">main</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h3>1.2 Arquivo providers.pp:</h3>

<p>Neste arquivo normalmente insiro configurações acerca de providers.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="kr">case</span> <span class="nv">$operatingsystem</span> <span class="p">{</span>
</span><span class='line'>    <span class="s1">&#39;Debian&#39;</span><span class="p">:</span> <span class="p">{</span>
</span><span class='line'>        <span class="nc">Package</span> <span class="p">{</span> <span class="nt">provider</span> <span class="p">=&gt;</span> <span class="s1">&#39;aptitude&#39;</span> <span class="p">}</span>
</span><span class='line'>    }
</span><span class='line'>    <span class="s1">&#39;RedHat&#39;</span><span class="p">:</span> <span class="p">{</span>
</span><span class='line'>        <span class="kr">case</span> <span class="nv">$operatingsystemrelease</span> <span class="p">{</span>
</span><span class='line'>            <span class="s1">&#39;4&#39;</span>    <span class="p">:</span> <span class="p">{</span>
</span><span class='line'>                <span class="nc">Package</span> <span class="p">{</span> <span class="nt">provider</span> <span class="p">=&gt;</span> <span class="s1">&#39;up2date&#39;</span> <span class="p">}</span>
</span><span class='line'>            }
</span><span class='line'>        <span class="p">}</span>
</span><span class='line'>    }
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h3>1.3 Arquivo extdata.pp:</h3>

<p>Neste arquivo determino o escopo da busca para external data.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="nv">$extlookup_datadir</span> <span class="o">=</span> <span class="s2">&quot;/etc/puppet/manifests/extdata&quot;</span>
</span><span class='line'><span class="nv">$extlookup_precedence</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;host/%{fqdn}&quot;</span><span class="p">,</span> <span class="s2">&quot;host/%{hostname}&quot;</span><span class="p">,</span> <span class="s2">&quot;domain/%{domain}&quot;</span><span class="p">,</span> <span class="s2">&quot;env/%{environment}&quot;</span><span class="p">,</span> <span class="s2">&quot;common&quot;</span><span class="p">]</span>
</span></code></pre></td></tr></table></div></figure>


<p>Apesar do recurso extlookup não ser muito utilizado depois da criação do HIERA,
ainda tenho módulos que utilizam esse tipo de configuração.</p>

<h3>1.4 Arquivo globals.pp:</h3>

<p>Neste arquivo coloco configurações globais, normalmente variáveis
que possam ser de interesse de vários módulos.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="nv">$dnssearch</span> <span class="o">=</span> <span class="p">[</span> <span class="s1">&#39;dominio&#39;</span><span class="p">,</span> <span class="s1">&#39;dominio.com.br&#39;</span><span class="p">,</span> <span class="p">]</span>
</span><span class='line'><span class="nv">$nameservers</span> <span class="o">=</span> <span class="p">[</span> <span class="s1">&#39;172.16.1.1&#39;</span><span class="p">,</span> <span class="p">]</span>
</span><span class='line'><span class="nv">$zabbixserver</span> <span class="o">=</span> <span class="s1">&#39;192.168.20.134&#39;</span>
</span><span class='line'><span class="nv">$baculaserver</span> <span class="o">=</span> <span class="s1">&#39;192.168.20.135&#39;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Lembre-se de declarar corretamente as variáveis de topo de escopo, veja o exemplo abaixo:</p>

<pre><code>$::dnsseearch
$::nameservers
$::zabbixserver
$::baculaserver
</code></pre>

<h3>1.5 Diretório classes</h3>

<p>Neste diretório costumo colocar classes simples, normalmente classes organizacionais que contém outras classes, ou mesmo classes <strong>base</strong> como a classe linux-server que é carregada em todos os nodes linux sem exceção.</p>

<p>Exemplo de manifest classes/linux-server.pp (classe organizacional):</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="kd">class</span> <span class="nc">linux</span><span class="err">-</span><span class="nc">server</span> <span class="p">{</span>
</span><span class='line'>
</span><span class='line'>        <span class="kn">include</span> <span class="nc">hosts</span><span class="c-Singleline">             # configura arquivo hosts</span>
</span><span class='line'>        <span class="nc">include</span> <span class="nc">mailaliases</span><span class="c-Singleline">       # configura aliases de correio local</span>
</span><span class='line'>        <span class="nc">include</span> <span class="nc">utils</span><span class="c-Singleline">             # instala pacotes dos sysadmins</span>
</span><span class='line'>        <span class="nc">include</span> <span class="nc">aptrepos</span><span class="c-Singleline">          # configura repositórios apt</span>
</span><span class='line'>        <span class="nc">include</span> <span class="nc">rcfiles</span><span class="c-Singleline">           # empurra screenrc e bashrc do root</span>
</span><span class='line'>        <span class="nc">include</span> <span class="nc">vimeditor</span><span class="c-Singleline">         # instala e configura vim e vimrc</span>
</span><span class='line'>        <span class="nc">include</span> <span class="nc">ntp</span><span class="c-Singleline">               # instala e cofigura ntp server</span>
</span><span class='line'>        <span class="nc">include</span> <span class="nc">locale</span><span class="c-Singleline">            # configura locale</span>
</span><span class='line'>        <span class="nc">include</span> <span class="nc">timezone</span><span class="c-Singleline">          # configure timezone</span>
</span><span class='line'>        <span class="nc">include</span> <span class="nc">users</span><span class="c-Singleline">             # cria usuários dos sysadmins</span>
</span><span class='line'>        <span class="nc">include</span> <span class="nc">suoders</span><span class="c-Singleline">           # configura sudoers</span>
</span><span class='line'>        <span class="nc">include</span> <span class="nc">ssh:server</span><span class="c-Singleline">        # instala e configura ssh server</span>
</span><span class='line'>        <span class="nc">include</span> <span class="nc">snmp::server</span><span class="c-Singleline">      # instala e configura snmp server</span>
</span><span class='line'>        <span class="nc">include</span> <span class="nc">zabbix::agent</span><span class="c-Singleline">     # instala e configura zabbix agent</span>
</span><span class='line'>        <span class="nc">include</span> <span class="nc">puppet::agent</span><span class="c-Singleline">     # configura puppet agent</span>
</span><span class='line'>        <span class="nc">include</span> <span class="nc">bacula::agent</span><span class="c-Singleline">     # instala e configura bacula agent</span>
</span><span class='line'>        <span class="nc">include</span> <span class="nc">postfix::local</span><span class="c-Singleline">    # instala e configura postfix local</span>
</span><span class='line'><span class="err">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Exemplo de manifest classes/utils.pp (classe simples):</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="kd">class</span> <span class="nc">utils</span> <span class="p">{</span><span class="c-Singleline"> </span>
</span><span class='line'><span class="c-Singleline"> </span>
</span><span class='line'><span class="c-Singleline">  # declarando que o tzdata tem que estar sempre em sua ultima versao</span>
</span><span class='line'>
</span><span class='line'>  <span class="nc">package</span> <span class="p">{</span> <span class="s1">&#39;tzdata&#39;</span><span class="p">:</span> <span class="nt">ensure</span> <span class="p">=&gt;</span> <span class="ss">latest</span> <span class="p">}</span><span class="c-Singleline"></span>
</span><span class='line'><span class="c-Singleline"> </span>
</span><span class='line'><span class="c-Singleline">  # declarando que os seguintes pacotes devem estar presentes (sysadmin packages)</span>
</span><span class='line'>
</span><span class='line'>  <span class="nc">package</span> <span class="p">{</span> <span class="p">[</span> <span class="s1">&#39;screen&#39;</span><span class="p">,</span>
</span><span class='line'>    <span class="s1">&#39;lynx&#39;</span><span class="p">,</span>
</span><span class='line'>    <span class="s1">&#39;elinks&#39;</span><span class="p">,</span>
</span><span class='line'>    <span class="s1">&#39;rsync&#39;</span><span class="p">,</span>
</span><span class='line'>    <span class="s1">&#39;telnet&#39;</span><span class="p">,</span>
</span><span class='line'>    <span class="s1">&#39;ftp&#39;</span><span class="p">,</span>
</span><span class='line'>    <span class="s1">&#39;wget&#39;</span><span class="p">,</span>
</span><span class='line'>    <span class="s1">&#39;bzip2&#39;</span><span class="p">,</span>
</span><span class='line'>    <span class="s1">&#39;unzip&#39;</span><span class="p">,</span>
</span><span class='line'>    <span class="s1">&#39;traceroute&#39;</span><span class="p">,</span>
</span><span class='line'>    <span class="s1">&#39;tcpdump&#39;</span><span class="p">,</span>
</span><span class='line'>    <span class="s1">&#39;iptraf&#39;</span><span class="p">,</span>
</span><span class='line'>    <span class="s1">&#39;ccze&#39;</span><span class="p">,</span>
</span><span class='line'>    <span class="s1">&#39;htop&#39;</span><span class="p">,</span>
</span><span class='line'>    <span class="s1">&#39;less&#39;</span><span class="p">,</span>
</span><span class='line'>    <span class="s1">&#39;dnsutils&#39;</span><span class="p">,</span>
</span><span class='line'>    <span class="s1">&#39;nmap&#39;</span><span class="p">,</span> <span class="p">]:</span>
</span><span class='line'>    <span class="nt">ensure</span>  <span class="p">=&gt;</span> <span class="ss">installed</span><span class="p">,</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>}
</span></code></pre></td></tr></table></div></figure>


<p>Considero uma classe simples algo que tem um manifest e no máximo um arquivo estático ou dinâmico (template), qualquer coisa maior recomendo construir um módulo, fica mais organizado.</p>

<p>Minhas classes simples utilizam os diretórios abaixo:</p>

<pre><code>/etc/puppet/files      # arquivos estáticos
/etc/puppet/templates  # arquivos dinâmicos
</code></pre>

<h3>1.6 Diretório nodes</h3>

<p>No diretório nodes costumo criar manifests separados para agrupar declarações de nodes em um mesmo contexto, fica mais organizado,
fácil de entender e administrar.</p>

<p>Exemplo de manifest nodes/apache.pp:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="kd">node</span> <span class="s2">&quot;apache01.dominio&quot;</span> <span class="p">{</span>
</span><span class='line'>   <span class="kn">include</span> <span class="nc">apache2</span>
</span><span class='line'>   <span class="kn">include</span> <span class="nc">php5</span>
</span><span class='line'>   <span class="kn">include</span> <span class="nc">aplicacao</span>
</span><span class='line'>}
</span><span class='line'><span class="kd">node</span> <span class="s2">&quot;apache02.dominio&quot;</span> <span class="p">{</span>
</span><span class='line'>   <span class="kn">include</span> <span class="nc">apache2</span>
</span><span class='line'>   <span class="kn">include</span> <span class="nc">php5</span>
</span><span class='line'>   <span class="kn">include</span> <span class="nc">aplicacao</span>
</span><span class='line'>}
</span><span class='line'><span class="kd">node</span> <span class="s2">&quot;apache03.dominio&quot;</span> <span class="p">{</span>
</span><span class='line'>   <span class="kn">include</span> <span class="nc">apache2</span>
</span><span class='line'>   <span class="kn">include</span> <span class="nc">php5</span>
</span><span class='line'>   <span class="kn">include</span> <span class="nc">aplicacao</span>
</span><span class='line'>}
</span></code></pre></td></tr></table></div></figure>


<p>Exemplo de manifest nodes/haproxy.pp:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="kd">node</span> <span class="s2">&quot;haproxy01.dominio&quot;</span> <span class="p">{</span>
</span><span class='line'>   <span class="kn">include</span> <span class="nc">haproxy</span>
</span><span class='line'>   <span class="kn">include</span> <span class="nc">haproxy::httpmode::phppool</span>
</span><span class='line'>   <span class="kn">include</span> <span class="nc">haproxy::httmode::phppool</span>
</span><span class='line'>}
</span><span class='line'><span class="kd">node</span> <span class="s2">&quot;haproxy02.dominio&quot;</span> <span class="p">{</span>
</span><span class='line'>   <span class="kn">include</span> <span class="nc">haproxy</span>
</span><span class='line'>   <span class="kn">include</span> <span class="nc">haproxy::tcpmode::imap</span>
</span><span class='line'>   <span class="kn">include</span> <span class="nc">haproxy::tcpmode::smtp</span>
</span><span class='line'>}
</span></code></pre></td></tr></table></div></figure>


<h2>2 Puppet.conf</h2>

<p>Algumas configurações importantes no puppet.conf dos agentes</p>

<h3>2.1 runinterval</h3>

<p>O parâmetro <strong>runinterval</strong> define o intervalo entre as checagens que o agente faz ao servidor puppet, neste exemplo ele fará a checagem a cada 3600 segundos ou 60 minutos.</p>

<pre><code>runinterval=3600
</code></pre>

<h3>2.2 splay &amp; splaylimit</h3>

<p>Podemos utilizar o splay para evitar que todos os agentes solicitem o catálogo ao mesmo tempo.</p>

<p>Com esse recurso ativo, o agente vai entrar em <strong>sleep</strong> quando chegar no momento de consultar o servidor. O agente será acionado dentro da
janela <strong>splaylimit</strong> de forma <strong>randômica</strong>, isto é fundamental para aliviar
a carga no puppetmaster em um cenário com muitos nodes.</p>

<p>Veja um exemplo de configuração de splay:</p>

<pre><code>splay=true
splaylimit=1800
runinterval=3600
</code></pre>

<p>No exemplo acima o <strong>splay</strong> está ligado e o limit está definido para 1800, logo ele vai trabalhar em uma janela de 1800 segundos após o tempo do <strong>runinterval</strong> ter se esgotado, com isto,
o tempo máximo entre checagens poder checar até 5400 segundos ou 90 minutos, lembrando que isso é o tempo máximo uma vez que os acionamentos são randômicos.</p>

<h2>3. Módulos</h2>

<h3>3.1 Pense em bibliotecas</h3>

<p>Pense em módulos como se fossem bibliotecas, quando for construir um módulo tente ao máximo construí-lo de forma que se alguém colocar este módulo no diretório /etc/puppet/modules tudo funcione de primeira, sem necessidade de alteração de código, permitindo
que alguma funcionalidade nova seja agregada ao seu ambiente
de forma simples e direta.</p>

<h3>3.2 Carregamento do módulo</h3>

<p>Construa módulos que tenham capacidade de serem lidos pelo auto-loader, isto significa que eles devem ter a estrutura recomendada
pela puppetlabs.</p>

<p>Módulo que não é carregado pelo auto-loader (jeito antigo):</p>

<pre><code># /etc/puppet/modules/modulename/init.pp
import "classes/*.pp"
import "definitions/*.pp"
</code></pre>

<p>Módulo que é carregado pelo auto-loader (jeito certo):</p>

<pre><code># /etc/puppet/modules/modulename/init.pp
class modulename {}
</code></pre>

<p>Se você construir um módulo incompatível com o auto-loader, você precisa fazer o import no arquivo site.pp</p>

<pre><code>import modulename
</code></pre>

<p>Se não fizer isso, o módulo não será carregado, por isto, procure seguir sempre as recomendações e crie módulos compatíveis com o auto-loader.</p>

<h3>3.3 Namespace</h3>

<p>Ao criar classes em módulos siga a nomenclatura abaixo:</p>

<pre><code>nome_do_modulo
nome_do_modulo::nome_da_classe
nome_do_modulo::nome_do_diretorio::nome_da_classe
</code></pre>

<p>Veja o exemplo do módulo apache:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="c-Singleline">  # /etc/puppetlabs/puppet/modules/apache/manifests</span>
</span><span class='line'><span class="c-Singleline">    # init.pp</span>
</span><span class='line'>      <span class="kd">class</span> <span class="nc">apache</span> <span class="p">{</span> }<span class="c-Singleline"></span>
</span><span class='line'><span class="c-Singleline">    # ssl.pp</span>
</span><span class='line'>      <span class="kd">class</span> <span class="nc">apache::ssl</span> <span class="p">{</span> }<span class="c-Singleline"></span>
</span><span class='line'><span class="c-Singleline">    # vhost.pp</span>
</span><span class='line'>      <span class="kd">define</span> <span class="nc">apache::vhost</span> <span class="p">()</span> <span class="p">{</span> }<span class="c-Singleline"></span>
</span><span class='line'><span class="c-Singleline">    # params/confs.pp</span>
</span><span class='line'>      <span class="kd">class</span> <span class="nc">apache::params::confs</span> <span class="p">{</span> }
</span></code></pre></td></tr></table></div></figure>


<p>Essa estrutura em escopo torna o nome das classes do módulo única, diferenciando dos demais módulos, evitando conflitos e problemas de carregamento, siga sempre esse modelo.</p>

<h3>3.4 Forge e Github</h3>

<p>Não comece do zero, pesquise e reutilize código existente no Puppet Forge e Github.</p>

<h3>3.5 Documentação</h3>

<p>Escreva um README detalhado, não deixe de preencher os metadados do seu módulo, crie a documentação de suas classes e definições usando
RDoc Markup.</p>

<p>Use os comandos <strong>puppet module</strong> e <strong>puppet doc</strong> para lhe ajudar com a documentação.</p>

<h2>4. Estilo de código</h2>

<p>Acesse a página <a href="http://docs.puppetlabs.com/guides/style_guide.html">style guide</a>, ou o meu post <a href="http://gutocarvalho.net/octopress/2013/04/20/puppet-style-guide">guia de estilos</a> para aprender a escrever seus manifests de forma mais eficiente.</p>

<h3>4.1 Puppet parser validate</h3>

<p>Para validar a sintaxe de código em um manifest você pode utilizar o comando puppet parser, veja abaixo o exemplo:</p>

<pre><code>puppet parser validate manifest.pp
</code></pre>

<h3>4.2 Puppet-lint</h3>

<p>Use o <a href="http://puppet-lint.com">puppet lint</a> para verificar se o seu manifest está com a estrutura de acordo com o <a href="http://docs.puppetlabs.com/guides/style_guide.html">style guide</a> do Puppet.</p>

<h2>5. ENC (External node classifier)</h2>

<p>Instale um ENC em seu ambiente, isto te permite acompanhar o ciclo de vida de seus node, e além disto, oferece controles para associar
classes parametrizadas a nodes ou grupos de nodes.</p>

<p>Os ENCs oferecem visualizações de status do seus nodes, é possível visualizar quando ocorreu uma mudança, é possível visualizar erros
decorrentes de mudanças, é possível extrair dados (fatos) dos nodes.</p>

<p>Os ENCs mais conhecidos são Puppet Dashboard e Foreman, o que possui
mais recursos é o Foreman.</p>

<h2>6. Repositório Puppetlabs</h2>

<p>Recomendo a utilização de pacotes do repositório oficial da Puppetlabs. Eles oferecem repositórios para Debian, Ubuntu, RHEL, Centos e derivados EL (Enterprise Linux).</p>

<p>Repositório APT</p>

<pre><code>apt.puppetlabs.com
</code></pre>

<p>Repositório YUM</p>

<pre><code>yum.puppetlabs.com
</code></pre>

<h2>7. Passenger</h2>

<p>O pacote puppetmaster por default usa um servidor web embutido chamado  &#8216;webrick&#8217;, este servidor web deve ser utilizado apenas para fins de desenvolvimento e testes, ele não suportará mais do que 25
conexões simultâneas, e se suportar irá alocar grande quantidade
de recursos de seu servidor, gerando extrema lentidão e alto
load. Em resumo o puppetmaster usando webrick não escala.</p>

<p>Em ambientes de produção é recomendando utilizar o pacote puppetmaster-passenger que já integra o puppetmaster ao Apache2
com mod-passenger, com isto, sua capacidade e robustez serão equivalentes a capacidade do apache2, este por sua vez é um servidor web reconhecidamente eficaz, rápido e escalável.</p>

<p>O passenger pode ser utilizado inclusive para rodar o puppet-dashboard.</p>

<h2>8. Orquestrador e MQ (Message Queue)</h2>

<p>É importante ter um orquestrador funcionando, eventualmente pode surgir a necessidade de rodar algum comando de forma paralela e
em tempo real em seus nodes, e você não pode ficar na mão nesse
momento.</p>

<p>O orquestrador que recomendo é o Marionette Collective (Mcollective ou MCO).</p>

<p>O Mcollective depende de um sistema MQ para funcionar, recomendo
o ActiveMQ. É possível utilizar o RabbitMQ, porém o criador do MCO
não é muito fã desse projeto, e algumas features do MCO só vão
funcionar com ActiveMQ.</p>

<p>Veja o post <a href="http://gutocarvalho.net/octopress/2013/02/07/instalando-mcollective-em-debian-squeeze-com-ambiente-puppet/">Intalando o Mcollective em Debian Squeeze</a> para aprender a instalar e configurar este orquestrador.</p>

<h2>9. Manuteção em Puppet Dashboard</h2>

<p>Se você está utilizando o ENC Puppet Dashboard, tome cuidado como crescimento do banco, se você não configurar o MYSQL corretamente
ou não levar em conta espaço em disco, pode ter alguma surpresa
depois de alguns meses, além da lentidão, um disk full pode para
seu ENC e será trabalhoso resolver o problema.</p>

<p>A puppetlabs oferece um <a href="http://docs.puppetlabs.com/dashboard/manual/1.2/maintaining.html">manual</a> com dados e comandos para fazer manutenção na base do dashboard, isto é muito útil e pode
te livrar de um grande problema.</p>

<h3>9.1 Otimização da base</h3>

<p>Para otimizar a sua base, basta rodar o comando abaixo na VM do ENC dentro do diretório do dashboard.</p>

<pre><code>sudo -u puppet-dashboard rake RAILS_ENV=production db:raw:optimize
</code></pre>

<h3>9.2 Limpeza da base</h3>

<p>Para limpar a base e manter os dados dos últimos 30 dias, basta rodar o comando abaixo no diretório do dashboard.</p>

<pre><code>sudo -u puppet-dashboard rake RAILS_ENV=production reports:prune upto=1 unit=mon
</code></pre>

<h3>9.3 Limpeza agendada</h3>

<p>Para inserir uma rotina de limpeza mensal do banco no cron, use o comando abaixo dentro do diretório do dashboard.</p>

<pre><code>sudo -u puppet-dashboard rake cron:cleanup
</code></pre>

<h2>10. Ambiente Puppet</h2>

<p>Dicas gerais:</p>

<ul>
<li>Se possível instale o PuppetMaster em uma VM dedicada.</li>
<li>Se possível instale o ENC em uma VM dedicada.</li>
<li>Se possível separe o banco do ENC em uma VM dedicada.</li>
<li>Se possível instale o Orquestrador + MQ em uma VM dedicada.</li>
</ul>


<p>Não vejo necessidade de rodar o Puppet, ENC ou Orquestrador em máquinas físicas, seu consumo de I/O e recursos não justifica isto, já o banco do ENC é interessante rodar em uma máquina física ligada
a um STORAGE com uma LUN em um RAID GROUP com discos rápidos.</p>

<h3>10.1 Características</h3>

<h4>10.1.1 PuppetMaster</h4>

<p>Para atender até 1000 nodes.</p>

<ul>
<li>4 Processadores</li>
<li>6 Gigas de RAM</li>
<li>BARRA com 30 GB</li>
<li>/VAR  com 120 GB (no caso de ter storeconfig ligado)</li>
<li>Distribuição 64 Bits</li>
<li>Recomendo Debian</li>
</ul>


<h4>10.1.2 ENC (app web sem banco)</h4>

<p>Para atender até 1000 nodes.</p>

<ul>
<li>2 Processadores</li>
<li>4 Gigas de RAM</li>
<li>BARRA com 30 GB</li>
<li>/VAR  com 60 GB</li>
<li>Distribuição 64 Bits</li>
<li>Recomendo Debian</li>
</ul>


<p>ENCs: Puppet Dashboard ou Foreman</p>

<p>Dá para colocar o PuppetDB na mesma máquina - se for o caso.</p>

<h4>10.1.3 ENC BANCO</h4>

<p>Para armazenar dados de até 1000 nodes.</p>

<ul>
<li>4 Processadores</li>
<li>6 Gigas de RAM</li>
<li>BARRA com 30 GB</li>
<li>/VAR  com 300 GB</li>
<li>Distribuição 64 Bits</li>
<li>Recomendo Debian</li>
</ul>


<h4>10.1.4 ORQUESTRADOR e MQ</h4>

<p>Para orquestrar até 1000 nodes.</p>

<ul>
<li>2 Processadores</li>
<li>4 Gigas de RAM</li>
<li>BARRA com 30 GB</li>
<li>/VAR  com 30 GB</li>
<li>Distribuição 64 Bits</li>
<li>Recomendo Debian</li>
</ul>


<p>ActiveMQ/RabbitMQ, Mcollective Client/Server.</p>

<p>[s]<br>
Guto</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Puppet Style Guide]]></title>
    <link href="http://gutocarvalho.net/octopress/2013/04/20/puppet-style-guide/"/>
    <updated>2013-04-20T16:03:00-03:00</updated>
    <id>http://gutocarvalho.net/octopress/2013/04/20/puppet-style-guide</id>
    <content type="html"><![CDATA[<h2>1. Puppet Guia de estilos</h2>

<p>Neste post eu vou trazer algumas dicas da puppetlabs sobre estilo de código. No site da Puppetlabs há uma página chamada <a href="http://docs.puppetlabs.com/guides/style_guide.html">style guide</a> explicando isto em inglês, eu pretendo me inspirar nesta página e estender as dicas na medida do possível.</p>

<p>O principal objetivo do style guide é apresentar como utilizar a sintaxe do Puppet de forma mais eficiente. Quando usamos a sintaxe coerentemente, temos ganhos na velocidade de processamento de nossos manifests, além disto, nosso código fica mais legível e elegante.</p>

<p>O parser do Puppet é bastante flexível e mesmo quando você produz algo fora padrões esperados, ele consegue entender, processar e aplicar as configurações descritas em seu manifest, contudo, ele levará mais tempo para processar o manifest, logo podemos dizer que certos tipos de código dificultam vida do parser, isto diminui a performance do agente quando ele for aplicar suas configurações, além disto, a aplicação do manifest pode ter algum comportamento inesperado.</p>

<p>Acompanhe o artigo para entender a melhor forma de usar sintaxe do Puppet.</p>

<h2>2. Dicas Gerais</h2>

<h3>2.1 Código de fácil leitura</h3>

<p>Se você tiver que optar em escrever um código obscuro e complexo e um código mais legível, procure sempre optar por escrever um código legível, seja para você, seja para outras pessoas. Isto pode parecer subjetivo, mas quando trabalhamos em equipe ou quando compartilhamos nosso código, quanto mais legível melhor. Além disto, isto evita situações em que você relê um código escrito meses atrás e não consegue entender o que estava fazendo.</p>

<h3>2.2 Herança em classes</h3>

<p>A Puppetlabs em regra geral pede para evitarmos o uso de herança entre classes, eles acreditam que isso dificulta a leitura e o entendimento do código.</p>

<p>Em minha opinião esse recurso pode ser muito útil em alguns casos, logo recomendo que você estude bem como funciona o conceito antes de utilizar, mais a frente voltaremos a falar disto.</p>

<h3>2.3 Módulos</h3>

<p>Quando for escrever módulos já planeje e desenhe seu módulo primeiro para funcionar com auto loading, segundo para que funcione tanto com um ENC quanto sem um ENC (External Node Classifier). O Foreman e Puppet Dashboard são exemplos de ENC.</p>

<p>Pense também em criar seu módulo utilizando o comando <strong>puppet module generate</strong> para que você siga a estrutura correta e recomendada,
escreva o README bem detalhado e não deixe de preencher os metadados.</p>

<h3>2.4 Declaração de classes</h3>

<p>Antes de entrar no assunto, vamos entender os conceitos DEFINIR e DECLARAR no universo Puppet.</p>

<p>Quando falarmos <strong>definir</strong>, significa que vamos escrever nosso manifest, ou seja, vamos colocar código lá.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="kd">class</span> <span class="nc">guto</span> <span class="p">{</span>
</span><span class='line'>  <span class="nc">user</span> <span class="p">{</span> <span class="s1">&#39;guto&#39;</span><span class="p">:</span>
</span><span class='line'>      <span class="nt">ensure</span> <span class="p">=&gt;</span> <span class="ss">present</span><span class="p">,</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>}
</span></code></pre></td></tr></table></div></figure>


<p>Quando falarmos <strong>declarar</strong>, significa que vamos executar o código de nosso manifest, ou seja, vamos aplicar a configuração.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="nc">class</span> <span class="p">{</span> <span class="s1">&#39;guto&#39;</span><span class="p">:</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>A puppetlabs não recomenda que durante a <strong>definição</strong> de uma classe, seja feita também <strong>declaração</strong> de outra classe.</p>

<p>Na minha opinião essa recomendação é feita pois este tipo declaração pode dificultar a ação do parser, aumentando o tempo de processamento do catálogo e além disto, pode gerar algum tipo de comportamento indesejável ao aplicar o manifest.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="kd">class</span> <span class="nc">sudo</span> <span class="p">{</span>
</span><span class='line'>
</span><span class='line'>  <span class="nc">package</span> <span class="p">{</span> <span class="s1">&#39;sudo&#39;</span><span class="p">:</span>
</span><span class='line'>      <span class="nt">ensure</span> <span class="p">=&gt;</span> <span class="ss">present</span><span class="p">,</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  
</span><span class='line'>  <span class="nc">class</span> <span class="p">{</span> <span class="s1">&#39;guto&#39;</span><span class="p">:</span> <span class="p">}</span>
</span><span class='line'>}
</span></code></pre></td></tr></table></div></figure>


<p>A declaração de classes deve ser utilizada o mais próximo possível do escopo do <strong>node</strong>, eles recomendam que sejamos conservadores com isto, contudo, há o recurso <strong>include</strong> que permite múltipla declaração de classes, se você precisar declarar outra classe, use include ou então verifique se não é melhor utilizar herança.</p>

<h2>3. Metadados do módulo</h2>

<p>Todo o módulo deve ter um arquivo de metadados, essa é uma recomendação importante principalmente se você deseja compartilhar seu módulo no forge ou github.</p>

<p>Quando você gera seu módulo usando o comando <strong>puppet module</strong>, o exemplo de metadados abaixo é criado, a partir daí é só ajustar.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>name 'myuser-mymodule'
</span><span class='line'>version '0.0.1'
</span><span class='line'>author 'Author of the module - for shared modules this is Puppet Labs'
</span><span class='line'>summary 'One line description of the module'
</span><span class='line'>description 'Longer description of the module including an example'
</span><span class='line'>license 'The license the module is release under - generally GPLv2 or Apache'
</span><span class='line'>project_page 'The URL where the module source is located'
</span><span class='line'>dependency 'otheruser/othermodule', '&gt;= 1.2.3'</span></code></pre></td></tr></table></div></figure>


<p>Um guia completo sobre a estrutura de um módulo pode ser encontrado no projeto <a href="https://github.com/puppetlabs/puppet-module-tool/blob/master/README.markdown">puppet-module-tool</a> no github.</p>

<h2>4. Indentação</h2>

<p>Se o seu manifest seguir as recomendações abaixo, estará dentro dos
moldes descritos no guia de estilo.</p>

<p>O seu manifest…</p>

<ul>
<li>Deve usar <strong>two-space soft tab</strong> (tab convertida para 2 espaços)</li>
<li>Não deve usar <strong>tab</strong> (literal)</li>
<li>Não deve ter <strong>trailing whitespace</strong> em seu código</li>
<li>Não deve extraploar <strong>80 caracteres</strong> por linha</li>
<li>Deve ter todas as <strong>setas</strong> (comma arrows) <strong>=></strong> alinhadas</li>
</ul>


<p>Eu particularmente uso soft tab no <strong>vim</strong> ou *sublime text 2** com 4 espaços, mas a recomendação deles é clara, 2 espaços para estar dentro dos padrões puppetlabs.</p>

<h3>4.1 Puppet-lint</h3>

<p>Use o <a href="http://puppet-lint.com">puppet lint</a> para verificar se o seu manifest está de acordo com o <a href="http://docs.puppetlabs.com/guides/style_guide.html">style guide</a> do Puppet.</p>

<h2>5. Comentários</h2>

<p>O Puppet permite vários tipo de comentários, porém o recomendado é utilizar hash.</p>

<p>A forma <strong>certa</strong> de fazer:</p>

<pre><code># Este é o tipo comentário recomendado
</code></pre>

<p>A puppetlabs não recomenda o uso dos estilos de comentários abaixo:</p>

<pre><code>// Comentário em formato não recomendado
/* Comentário em formato não recomendado */
</code></pre>

<h2>6. Quoting</h2>

<p>Todas as <strong>strings</strong> que não contenham <strong>variáveis</strong> devem usar <strong>single quotes</strong>.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="err">&#39;string</span> <span class="err">em</span> <span class="err">single</span> <span class="err">quote&#39;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Quando for necessário <strong>interpolar</strong> strings e variáveis, use <strong>double quoting</strong> e <strong>chaves</strong> nas variáveis para identificá-las.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="err">&quot;string</span> <span class="err">e</span> <span class="err">${variável}&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>Valores específicos de <strong>atributos</strong> não precisam de quote.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="err">ensure</span> <span class="err">=&gt;</span> <span class="err">present,</span>
</span></code></pre></td></tr></table></div></figure>


<p>O uso de <strong>quotes</strong> é opcional quando uma <strong>string</strong> for <strong>alfa-numérica</strong> e desde que não seja o <strong>título</strong> de um recurso.</p>

<h3>6.1 Interpolação de variável</h3>

<p>A forma <strong>certa</strong> de fazer:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="err">&quot;/etc/${file}.conf&quot;</span>
</span><span class='line'><span class="err">&quot;${::operatingsystem}</span> <span class="err">is</span> <span class="err">not</span> <span class="err">supported</span> <span class="err">by</span> <span class="err">${module_name}&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<p>A forma <strong>não</strong> recomendada:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="err">&quot;/etc/</span><span class="nv">$file</span><span class="m">.</span><span class="ss">conf</span><span class="s2">&quot;</span>
</span><span class='line'><span class="s2">&quot;</span><span class="nv">$::operatingsystem</span> <span class="err">is</span> <span class="err">not</span> <span class="err">supported</span> <span class="err">by</span> <span class="nv">$module_name</span><span class="s2">&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<h3>6.2 Valor de atributos</h3>

<p>A forma <strong>certa</strong> de fazer:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="err">mode</span> <span class="err">=&gt;</span> <span class="nv">$my_mode</span>
</span></code></pre></td></tr></table></div></figure>


<p>A forma <strong>não</strong> recomendada:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="err">mode</span> <span class="err">=&gt;</span> <span class="err">&quot;</span><span class="nv">$my_mode</span><span class="s2">&quot;</span>
</span><span class='line'><span class="s2">mode =&gt; &quot;</span><span class="err">$</span><span class="p">{</span><span class="ss">my_mode</span><span class="p">}</span><span class="err">&quot;</span>
</span></code></pre></td></tr></table></div></figure>


<h2>7. Resources</h2>

<h3>7.1 Resource names</h3>

<p><strong>Todos</strong> os resource names devem usar <strong>quote</strong>, no entanto, o puppet permite o uso de <strong>nomes</strong> para <strong>títulos</strong> sem quotes desde que o nome não tenha hífen ou espaços, contudo, para seguir um padrão consistente, use sempre quote.</p>

<p><strong>Variáveis</strong> ou <strong>fatos</strong> não necessitam de <strong>quotes</strong> quando forem utilizadas como título.</p>

<p>A forma <strong>certa</strong> de fazer:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="nc">package</span> <span class="p">{</span> <span class="s1">&#39;htop&#39;</span><span class="p">:</span> <span class="nt">ensure</span> <span class="p">=&gt;</span> <span class="ss">present</span> <span class="p">}</span>
</span><span class='line'><span class="nc">package</span> <span class="p">{</span> <span class="nv">$package_name</span><span class="p">:</span> <span class="nt">ensure</span> <span class="p">=&gt;</span> <span class="ss">present</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>A forma <strong>não</strong> recomendada:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'>    <span class="nc">package</span> <span class="p">{</span> <span class="ss">htop</span><span class="p">:</span> <span class="nt">ensure</span> <span class="p">=&gt;</span> <span class="ss">present</span> <span class="p">}</span>
</span><span class='line'>    <span class="nc">package</span> <span class="p">{</span> <span class="s2">&quot;</span><span class="si">${package_name}</span><span class="s2">&quot;</span><span class="p">:</span> <span class="nt">ensure</span> <span class="p">=&gt;</span> <span class="ss">present</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h3>7.2. Alinhamento</h3>

<p>Todos os atributos e valores de um recurso devem estar alinhados em seu bloco,
as setas devem ter um espaço após o nome do atributo mais longo.</p>

<p>Apesar de ser uma recomendação estética, isto facilita muito a leitura.</p>

<p>A forma <strong>certa</strong> de fazer:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="nc">package</span> <span class="p">{</span> <span class="s1">&#39;pacote&#39;</span><span class="p">:</span>
</span><span class='line'>       <span class="nt">ensure</span> <span class="p">=&gt;</span> <span class="ss">present</span><span class="p">,</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nc">service</span> <span class="p">{</span> <span class="s1">&#39;servico&#39;</span><span class="p">:</span>
</span><span class='line'>  <span class="nt">ensure</span>     <span class="p">=&gt;</span> <span class="ss">running</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">enable</span>     <span class="p">=&gt;</span> <span class="ss">true</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">hasrestart</span> <span class="p">=&gt;</span> <span class="ss">true</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">hasstatus</span>  <span class="p">=&gt;</span> <span class="ss">true</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">require</span>    <span class="p">=&gt;</span> <span class="nc">Package</span><span class="p">[</span><span class="s1">&#39;pacote&#39;</span><span class="p">],</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nc">file</span> <span class="p">{</span> <span class="s1">&#39;main.cf&#39;</span><span class="p">:</span>
</span><span class='line'>  <span class="nt">path</span>    <span class="p">=&gt;</span> <span class="s2">&quot;/etc/pacote/pacote.conf&quot;</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">source</span>  <span class="p">=&gt;</span> <span class="s2">&quot;/root/puppet/pacote.conf&quot;</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">owner</span>   <span class="p">=&gt;</span> <span class="s1">&#39;root&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">group</span>   <span class="p">=&gt;</span> <span class="s1">&#39;root&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">mode</span>    <span class="p">=&gt;</span> <span class="m">644</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">require</span> <span class="p">=&gt;</span> <span class="nc">Package</span><span class="p">[</span><span class="s1">&#39;pacote&#39;</span><span class="p">],</span>
</span><span class='line'>  <span class="nt">notify</span>  <span class="p">=&gt;</span> <span class="nc">Service</span><span class="p">[</span><span class="s1">&#39;servico&#39;</span><span class="p">],</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>A forma <strong>não</strong> recomendada:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="nc">package</span> <span class="p">{</span> <span class="s1">&#39;pacote&#39;</span><span class="p">:</span>
</span><span class='line'>  <span class="nt">ensure</span> <span class="p">=&gt;</span> <span class="ss">present</span><span class="p">,</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nc">service</span> <span class="p">{</span> <span class="s1">&#39;servico&#39;</span><span class="p">:</span>
</span><span class='line'>  <span class="nt">ensure</span> <span class="p">=&gt;</span> <span class="ss">running</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">enable</span> <span class="p">=&gt;</span> <span class="ss">true</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">hasrestart</span> <span class="p">=&gt;</span> <span class="ss">true</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">hasstatus</span> <span class="p">=&gt;</span> <span class="ss">true</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">require</span> <span class="p">=&gt;</span> <span class="nc">Package</span><span class="p">[</span><span class="s1">&#39;pacote&#39;</span><span class="p">],</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nc">file</span> <span class="p">{</span> <span class="s1">&#39;main.cf&#39;</span><span class="p">:</span>
</span><span class='line'>  <span class="nt">path</span> <span class="p">=&gt;</span> <span class="s2">&quot;/etc/pacote/pacote.conf&quot;</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">source</span> <span class="p">=&gt;</span> <span class="s2">&quot;/root/puppet/pacote.conf&quot;</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">owner</span> <span class="p">=&gt;</span> <span class="s1">&#39;root&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">group</span> <span class="p">=&gt;</span> <span class="s1">&#39;root&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">mode</span> <span class="p">=&gt;</span> <span class="m">644</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">require</span> <span class="p">=&gt;</span> <span class="nc">Package</span><span class="p">[</span><span class="s1">&#39;pacote&#39;</span><span class="p">],</span>
</span><span class='line'>  <span class="nt">notify</span> <span class="p">=&gt;</span> <span class="nc">Service</span><span class="p">[</span><span class="s1">&#39;servico&#39;</span><span class="p">],</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h3>7.3. Ordenação de atributos</h3>

<p>Se a declaração de um recurso possuir o atributo <strong>ensure</strong>, este deve preceder qualquer outro atributo, ele sempre vem primeiro.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="nc">file</span> <span class="p">{</span> <span class="s1">&#39;/tmp/readme.txt&#39;</span><span class="p">:</span>
</span><span class='line'>  <span class="nt">ensure</span> <span class="p">=&gt;</span> <span class="ss">file</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">owner</span>  <span class="p">=&gt;</span> <span class="s1">&#39;0&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">group</span>  <span class="p">=&gt;</span> <span class="s1">&#39;0&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">mode</span>   <span class="p">=&gt;</span> <span class="s1">&#39;0644&#39;</span><span class="p">,</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h3>7.4 Múltiplos resources</h3>

<p>A puppetlabs só recomenda o uso de múltiplos resources para tornar o código mais legível, portando, evite o uso a não ser que isso seja realmente necessário.</p>

<p>A forma <strong>certa</strong> de fazer:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="nc">file</span> <span class="p">{</span> <span class="s1">&#39;/tmp/a&#39;</span><span class="p">:</span>
</span><span class='line'>  <span class="nt">content</span> <span class="p">=&gt;</span> <span class="s1">&#39;a&#39;</span><span class="p">,</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nc">file</span> <span class="p">{</span> <span class="s1">&#39;/tmp/b&#39;</span><span class="p">:</span>
</span><span class='line'>  <span class="nt">content</span> <span class="p">=&gt;</span> <span class="s1">&#39;b&#39;</span><span class="p">,</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nc">file</span> <span class="p">{</span> <span class="s1">&#39;/tmp/c&#39;</span><span class="p">:</span>
</span><span class='line'>  <span class="nt">content</span> <span class="p">=&gt;</span> <span class="s1">&#39;c&#39;</span><span class="p">,</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>A forma <strong>não</strong> recomendada:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="nc">file</span> <span class="p">{</span>
</span><span class='line'>  <span class="s2">&quot;/tmp/a&quot;</span><span class="p">:</span>
</span><span class='line'>      <span class="nt">content</span> <span class="p">=&gt;</span> <span class="s2">&quot;a&quot;</span><span class="p">;</span>
</span><span class='line'>  <span class="s2">&quot;/tmp/b&quot;</span><span class="p">:</span>
</span><span class='line'>      <span class="nt">content</span> <span class="p">=&gt;</span> <span class="s2">&quot;b&quot;</span><span class="p">;</span>
</span><span class='line'>  <span class="s2">&quot;/tmp/c&quot;</span><span class="p">:</span>
</span><span class='line'>      <span class="nt">content</span> <span class="p">=&gt;</span> <span class="s2">&quot;c&quot;</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h3>7.5 Links simbólicos</h3>

<p>Apenas para deixar o código mais limpo e legível, recomenda-se declarar o link simbólico de forma explícita.</p>

<p>A forma <strong>certa</strong> de fazer:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'>    <span class="nc">file</span> <span class="p">{</span> <span class="s1">&#39;/var/log/syslog&#39;</span><span class="p">:</span>
</span><span class='line'>      <span class="nt">ensure</span> <span class="p">=&gt;</span> <span class="ss">link</span><span class="p">,</span>
</span><span class='line'>      <span class="nt">target</span> <span class="p">=&gt;</span> <span class="s1">&#39;/var/log/messages&#39;</span><span class="p">,</span>
</span><span class='line'>    <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>A forma <strong>não</strong> recomendada:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'>    <span class="nc">file</span> <span class="p">{</span> <span class="s1">&#39;/var/log/syslog&#39;</span><span class="p">:</span>
</span><span class='line'>      <span class="nt">ensure</span> <span class="p">=&gt;</span> <span class="s1">&#39;/var/log/messages&#39;</span><span class="p">,</span>
</span><span class='line'>    <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h3>7.6 File modes</h3>

<p>Devemos representar as permissões de arquivos e diretórios com 4 dígitos ao invés de 3 dígitos.</p>

<p>As permissões devem ser declaradas usando <strong>single-quote</strong>, <strong>sempre</strong>.</p>

<p>A forma <strong>certa</strong> de fazer:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="nc">file</span> <span class="p">{</span> <span class="s1">&#39;/var/log/syslog&#39;</span><span class="p">:</span>
</span><span class='line'>  <span class="nt">ensure</span> <span class="p">=&gt;</span> <span class="ss">present</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">mode</span>   <span class="p">=&gt;</span> <span class="s1">&#39;0644&#39;</span><span class="p">,</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>A forma <strong>não</strong> recomendada:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="nc">file</span> <span class="p">{</span> <span class="s1">&#39;/var/log/syslog&#39;</span><span class="p">:</span>
</span><span class='line'>  <span class="nt">ensure</span> <span class="p">=&gt;</span> <span class="ss">present</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">mode</span>   <span class="p">=&gt;</span> <span class="m">644</span><span class="p">,</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h3>7.7 Resource Defaults</h3>

<p>Podemos declarar alguns padrões para uso de recursos, porém, isso deve ser utilizado com cuidado, este tipo de declaração deve ser feita apenas no nível mais alto do seu ecosistema de manifests. Especificamente, eles devem ser declarados:</p>

<ul>
<li>No topo de escopo dentro do arquivo site.pp</li>
<li>Em classes que não serão herdadas</li>
<li>Em classes em que não você não declara outras classes</li>
</ul>


<p>Se essas recomendações não forem seguidas poderão ocorrer comportamentos inesperados durante a execução de seus manifests, principalmente se
essa configuração for propagada ou herdada de alguma forma.</p>

<p>A forma <strong>certa</strong> de fazer:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="c-Singleline"># /etc/puppetlabs/puppet/manifests/site.pp:</span>
</span><span class='line'><span class="nc">File</span> <span class="p">{</span>
</span><span class='line'>  <span class="nt">mode</span>  <span class="p">=&gt;</span> <span class="s1">&#39;0644&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">owner</span> <span class="p">=&gt;</span> <span class="s1">&#39;root&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">group</span> <span class="p">=&gt;</span> <span class="s1">&#39;root&#39;</span><span class="p">,</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>A forma <strong>não</strong> recomendada:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="c-Singleline">#/etc/puppetlabs/puppet/modules/ssh/manifests/init.pp</span>
</span><span class='line'><span class="nc">File</span> <span class="p">{</span>
</span><span class='line'>  <span class="nt">mode</span>  <span class="p">=&gt;</span> <span class="s1">&#39;0600&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">owner</span> <span class="p">=&gt;</span> <span class="s1">&#39;nobody&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">group</span> <span class="p">=&gt;</span> <span class="s1">&#39;nogroup&#39;</span><span class="p">,</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nc">class</span> <span class="p">{</span><span class="s1">&#39;ssh::client&#39;</span><span class="p">:</span>
</span><span class='line'>  <span class="nt">ensure</span> <span class="p">=&gt;</span> <span class="ss">present</span><span class="p">,</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h2>8. Condicionais</h2>

<h3>8.1 Mantenha suas declarações simples</h3>

<p>A Puppetalabs não recomenda misturar resource types e condicionais, isto está bem ligado ao uso de <strong>seletores</strong>, portanto, faça o tratamento condicional fora do resource type, é mais eficaz do ponto de vista de processamento do catálogo e além disto, fica mais legível e elegante.</p>

<p>A forma <strong>certa</strong> de fazer:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="nv">$file_mode</span> <span class="o">=</span> <span class="nv">$::operatingsystem</span> <span class="p">?</span> <span class="p">{</span>
</span><span class='line'>  <span class="ss">debian</span> <span class="p">=&gt;</span> <span class="s1">&#39;0007&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="ss">redhat</span> <span class="p">=&gt;</span> <span class="s1">&#39;0776&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="ss">fedora</span> <span class="p">=&gt;</span> <span class="s1">&#39;0007&#39;</span><span class="p">,</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nc">file</span> <span class="p">{</span> <span class="s1">&#39;/tmp/readme.txt&#39;</span><span class="p">:</span>
</span><span class='line'>  <span class="nt">content</span> <span class="p">=&gt;</span> <span class="s2">&quot;Hello World</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">mode</span>    <span class="p">=&gt;</span> <span class="nv">$file_mode</span><span class="p">,</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>A forma <strong>não</strong> recomendada:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="nc">file</span> <span class="p">{</span> <span class="s1">&#39;/tmp/readme.txt&#39;</span><span class="p">:</span>
</span><span class='line'>  <span class="nt">mode</span> <span class="p">=&gt;</span> <span class="nv">$::operatingsystem</span> <span class="p">?</span> <span class="p">{</span>
</span><span class='line'>  <span class="ss">debian</span> <span class="p">=&gt;</span> <span class="s1">&#39;0777&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="ss">redhat</span> <span class="p">=&gt;</span> <span class="s1">&#39;0776&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="ss">fedora</span> <span class="p">=&gt;</span> <span class="s1">&#39;0007&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h3>8.2 Estado Default em Case e Seletores</h3>

<p>Tanto em CASE quanto em SELETORES, podemos utilizar o statement DEFAULT, ou seja, isto determina um valor default se não casar com nenhuma opção do CASE ou SELETOR.</p>

<p>case:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="kr">case</span> <span class="nv">$var</span> <span class="p">{</span>
</span><span class='line'>  <span class="ss">valor1</span><span class="p">:</span>  <span class="p">{</span> <span class="err">bloco</span> <span class="err">de</span> <span class="err">código</span> }
</span><span class='line'>  <span class="ss">valor2</span><span class="p">:</span>  <span class="p">{</span> <span class="err">bloco</span> <span class="err">de</span> <span class="err">código</span> }
</span><span class='line'>  <span class="kr">default</span><span class="p">:</span> <span class="p">{</span> <span class="err">bloco</span> <span class="err">de</span> <span class="err">codigo</span> }
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>seletor:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="nv">$file_mode</span> <span class="o">=</span> <span class="nv">$::operatingsystem</span> <span class="p">?</span> <span class="p">{</span>
</span><span class='line'>  <span class="ss">debian</span>  <span class="p">=&gt;</span> <span class="s1">&#39;0007&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="ss">redhat</span>  <span class="p">=&gt;</span> <span class="s1">&#39;0776&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="ss">fedora</span>  <span class="p">=&gt;</span> <span class="s1">&#39;0007&#39;</span><span class="p">,</span>
</span><span class='line'>  <span class="kr">default</span> <span class="p">=&gt;</span> <span class="s1">&#39;0077&#39;</span><span class="p">,</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>A puppetlabs recomenda que a opção default esteja presente em qualquer tratamento condicional que o suporte, e recomenda ainda que seja associada a função fail, esta função interrompe o processamento do catálogo caso o sistema
não seja compatível com o tratamento condicional definido.</p>

<p>exemplo:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="kr">case</span> <span class="nv">$::operatingsystem</span> <span class="p">{</span>
</span><span class='line'>  <span class="ss">centos</span><span class="p">,</span> <span class="ss">redhat</span><span class="p">:</span> <span class="p">{</span> <span class="nv">$apache</span> <span class="o">=</span> <span class="s2">&quot;httpd&quot;</span> }
</span><span class='line'>  <span class="ss">debian</span><span class="p">,</span> <span class="ss">ubuntu</span><span class="p">:</span> <span class="p">{</span> <span class="nv">$apache</span> <span class="o">=</span> <span class="s2">&quot;apache2&quot;</span> }
</span><span class='line'>  <span class="kr">default</span><span class="p">:</span> <span class="p">{</span> <span class="nf">fail</span><span class="p">(</span><span class="s2">&quot;Sistema operacional não reconhecido&quot;</span><span class="p">)</span> }
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>No exemplo acima, o <strong>CASE</strong> verifica qual é o sistema operacional do node - usando o <strong>fato</strong>, caso o valor detectado não case com nenhuma das opções do CASE, o <strong>default</strong> é acionado e executa a função <strong>fail</strong>, isto interrompe o processamento do catálogo e retorna um erro que poderá ser visualizado em seu ENC ou no log do agente.</p>

<h2>9. Classes</h2>

<p>Recomenda-se separar classes e definições em arquivos distintos no diretório manifest de seu módulo.</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="c-Singleline"> # /etc/puppetlabs/puppet/modules/apache/manifests</span>
</span><span class='line'>
</span><span class='line'><span class="c-Singleline">    # init.pp</span>
</span><span class='line'>      <span class="kd">class</span> <span class="nc">apache</span> <span class="p">{</span> }<span class="c-Singleline"></span>
</span><span class='line'><span class="c-Singleline">    # ssl.pp</span>
</span><span class='line'>      <span class="kd">class</span> <span class="nc">apache::ssl</span> <span class="p">{</span> }<span class="c-Singleline"></span>
</span><span class='line'><span class="c-Singleline">    # virtual_host.pp</span>
</span><span class='line'>      <span class="kd">define</span> <span class="nc">apache::virtual_host</span> <span class="p">()</span> <span class="p">{</span> }
</span></code></pre></td></tr></table></div></figure>


<p>É importante entender que isto não altera em nada o funcionamento do módulo,
tem o mesmo efeito de declarar tudo no arquivo init.pp, contudo, separando
os arquivos temos uma estrutura que facilita o entendimento e torna o todo
mais legível.</p>

<h3>9.1 Nomes de classes</h3>

<p>Observe que o nome das classes dentro dos arquivos utiliza escopos, a regra é clara, o nome da classe recebe o nome do módulo + o nome da classe, veja o exemplo:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="c-Singleline"># /etc/puppetlabs/puppet/modules/apache/manifests</span>
</span><span class='line'><span class="c-Singleline"> # ssl.pp</span>
</span><span class='line'>  <span class="kd">class</span> <span class="nc">apache::ssl</span>
</span></code></pre></td></tr></table></div></figure>


<p>Caso você queria criar um diretório para organizar melhor seu módulo a regra passa a incluir o nome do diretório, veja o exemplo:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="c-Singleline">    </span>
</span><span class='line'><span class="c-Singleline"># /etc/puppetlabs/puppet/modules/apache/manifests</span>
</span><span class='line'><span class="c-Singleline"> # conf/parameters.pp</span>
</span><span class='line'>  <span class="kd">class</span> <span class="nc">apache::conf::parameters</span>
</span></code></pre></td></tr></table></div></figure>


<p>Essa estrutura em escopo torna o nome das classes do módulo única, diferenciando dos demais módulos, evitando conflitos e problemas
de carregamento, siga sempre essa estrutura.</p>

<h3>9.2 Organização interna</h3>

<p>As classes precisam ser organizadas de forma a manter um estilo e estrutura consistente. Abaixo uma lista com itens importantes encontrados em um classe
que foi construída seguindo a lógica do style guide.</p>

<p>A classe&#8230;</p>

<ul>
<li>Deve definir parâmetros</li>
<li>Deve validar parâmetros</li>
<li>Deve interromper a execução em falha de validação</li>
<li>Deve oferecer parâmetros default</li>
<li>Pode ter declaração de variáveis locais</li>
<li>Pode ter relação com outras classes

<ul>
<li>Class[&#8216;apache&#8217;] -> Class[&#8216;local_yum&#8217;]</li>
</ul>
</li>
<li>Pode sobrescrever (override) resources</li>
<li>Pode declarar resources</li>
<li>Pode declarar relação entre resources dentro de condicionais</li>
</ul>


<p>Exemplo de uma classe que segue essas recomendações:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="kd">class</span> <span class="nc">myservice</span><span class="p">(</span><span class="nv">$ensure</span><span class="p">=</span><span class="s1">&#39;running&#39;</span><span class="p">)</span> <span class="p">{</span><span class="c-Singleline"></span>
</span><span class='line'>
</span><span class='line'><span class="c-Singleline">     # checagem condicional</span>
</span><span class='line'>  
</span><span class='line'>      <span class="kr">if</span> <span class="nv">$ensure</span> <span class="o">in</span> <span class="p">[</span> <span class="ss">running</span><span class="p">,</span> <span class="ss">stopped</span> <span class="p">]</span> <span class="p">{</span>
</span><span class='line'>        <span class="nv">$ensure_real</span> <span class="o">=</span> <span class="nv">$ensure</span>
</span><span class='line'>      } <span class="kr">else</span> <span class="p">{</span><span class="c-Singleline"></span>
</span><span class='line'><span class="c-Singleline">        # interrompendo execução em caso de falta de parâmetro</span>
</span><span class='line'>        <span class="nf">fail</span><span class="p">(</span><span class="s1">&#39;ensure parameter must be running or stopped&#39;</span><span class="p">)</span>
</span><span class='line'>      }
</span><span class='line'>      <span class="kr">case</span> <span class="nv">$::operatingsystem</span> <span class="p">{</span>
</span><span class='line'>        <span class="ss">centos</span><span class="p">:</span> <span class="p">{</span>
</span><span class='line'>          <span class="nv">$package_list</span> <span class="o">=</span> <span class="s1">&#39;openssh-server&#39;</span>
</span><span class='line'>        }
</span><span class='line'>        <span class="ss">solaris</span><span class="p">:</span> <span class="p">{</span>
</span><span class='line'>          <span class="nv">$package_list</span> <span class="o">=</span> <span class="p">[</span> <span class="ss">SUNWsshr</span><span class="p">,</span> <span class="ss">SUNWsshu</span> <span class="p">]</span>
</span><span class='line'>        }
</span><span class='line'>        <span class="kr">default</span><span class="p">:</span> <span class="p">{</span><span class="c-Singleline"></span>
</span><span class='line'><span class="c-Singleline">          # interrompendo execução caso o sistema operacional seja desconhecido</span>
</span><span class='line'>          <span class="nf">fail</span><span class="p">(</span><span class="s2">&quot;Module </span><span class="si">${module_name}</span><span class="s2"> does not support </span><span class="si">${::operatingsystem}</span><span class="s2">&quot;</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'>        }
</span><span class='line'>
</span><span class='line'>      <span class="p">}</span><span class="c-Singleline"></span>
</span><span class='line'>
</span><span class='line'><span class="c-Singleline">      # variável de uso local</span>
</span><span class='line'>      <span class="nv">$variable</span> <span class="o">=</span> <span class="s1">&#39;something&#39;</span>
</span><span class='line'>
</span><span class='line'>      <span class="nc">Package</span> <span class="p">{</span> <span class="nt">ensure</span> <span class="p">=&gt;</span> <span class="ss">present</span><span class="p">,</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>      <span class="nc">File</span> <span class="p">{</span> <span class="nt">owner</span> <span class="p">=&gt;</span> <span class="s1">&#39;0&#39;</span><span class="p">,</span> <span class="nt">group</span> <span class="p">=&gt;</span> <span class="s1">&#39;0&#39;</span><span class="p">,</span> <span class="nt">mode</span> <span class="p">=&gt;</span> <span class="s1">&#39;0644&#39;</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>      <span class="nc">package</span> <span class="p">{</span> <span class="nv">$package_list</span><span class="p">:</span> <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>      <span class="nc">file</span> <span class="p">{</span> <span class="s2">&quot;/tmp/</span><span class="si">${variable}</span><span class="s2">&quot;</span><span class="p">:</span>
</span><span class='line'>        <span class="nt">ensure</span> <span class="p">=&gt;</span> <span class="ss">present</span><span class="p">,</span>
</span><span class='line'>      <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>      <span class="nc">service</span> <span class="p">{</span> <span class="s1">&#39;myservice&#39;</span><span class="p">:</span>
</span><span class='line'>        <span class="nt">ensure</span>    <span class="p">=&gt;</span> <span class="nv">$ensure_real</span><span class="p">,</span>
</span><span class='line'>        <span class="nt">hasstatus</span> <span class="p">=&gt;</span> <span class="ss">true</span><span class="p">,</span>
</span><span class='line'>      <span class="p">}</span>
</span><span class='line'>    }
</span></code></pre></td></tr></table></div></figure>


<h3>9.3 Relações encadeadas</h3>

<p>O puppet nos oferece duas formas de trabalhar com relações, a primeira é usando meta-parâmetros como <strong>require</strong>, <strong>before</strong>, <strong>notify</strong> e <strong>subscribe</strong> e a segunda é usando uma cadeia de relações, para entender veja dois exemplos básicos, o primeiro precedência e o segundo notificação.</p>

<p><strong>Precedência via meta-parâmetro</strong></p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="nc">package</span> <span class="p">{</span> <span class="s1">&#39;httpd&#39;</span><span class="p">:</span>
</span><span class='line'>  <span class="nt">ensure</span> <span class="p">=&gt;</span> <span class="ss">installed</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">before</span> <span class="p">=&gt;</span> <span class="nc">Service</span><span class="p">[</span><span class="ss">httpd</span><span class="p">],</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="nc">service</span> <span class="p">{</span> <span class="s1">&#39;httpd&#39;</span><span class="p">:</span>
</span><span class='line'>  <span class="nt">ensure</span> <span class="p">=&gt;</span> <span class="ss">running</span><span class="p">,</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p><strong>Precedência usando cadeia de relacionamento</strong></p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="nc">Package</span><span class="p">[</span><span class="s1">&#39;httpd&#39;</span><span class="p">]</span> <span class="err">-&gt;</span> <span class="ss">Service</span><span class="err">[</span><span class="s1">&#39;httpd&#39;</span><span class="p">]</span>
</span></code></pre></td></tr></table></div></figure>


<p><strong>Notificando via meta-parâmetro</strong></p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="nc">file</span> <span class="p">{</span> <span class="s1">&#39;httpdconf&#39;</span><span class="p">:</span>
</span><span class='line'>  <span class="nt">path</span>   <span class="p">=&gt;</span> <span class="s1">&#39;/etc/httpd/httpd.conf&#39;</span>
</span><span class='line'>  <span class="nt">ensure</span> <span class="p">=&gt;</span> <span class="ss">present</span><span class="p">,</span>
</span><span class='line'>  <span class="nt">notify</span> <span class="p">=&gt;</span> <span class="nc">Service</span><span class="p">[</span><span class="ss">httpd</span><span class="p">]</span>
</span><span class='line'>
</span><span class='line'><span class="ss">service</span> <span class="p">{</span> <span class="s1">&#39;httpd&#39;</span><span class="err">:</span>
</span><span class='line'>  <span class="ss">ensure</span> <span class="p">=&gt;</span> <span class="ss">running</span><span class="p">,</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p><strong>Notificando via cadeia de relacionamento</strong></p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="nc">File</span><span class="p">[</span><span class="s1">&#39;httpdconf&#39;</span><span class="p">]</span> <span class="err">~&gt;</span> <span class="ss">Service</span><span class="err">[</span><span class="s1">&#39;httpd&#39;</span><span class="p">]</span>
</span></code></pre></td></tr></table></div></figure>


<p>Cadeias de relacionamento são recursos úteis mas devem ser utilizados com cuidado, recomenda-se
utilizar cadeias com regras da esquera para direta sempre, evite outras variações</p>

<p>A forma <strong>certa</strong> de fazer:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="nc">Package</span><span class="p">[</span><span class="s1">&#39;httpd&#39;</span><span class="p">]</span> <span class="err">-&gt;</span> <span class="ss">Service</span><span class="err">[</span><span class="s1">&#39;httpd&#39;</span><span class="p">]</span>
</span><span class='line'><span class="ss">File</span><span class="err">[</span><span class="s1">&#39;httpconf&#39;</span><span class="p">]</span> <span class="err">~&gt;</span> <span class="ss">Service</span><span class="err">[</span><span class="s1">&#39;httpd&#39;</span><span class="p">]</span>
</span></code></pre></td></tr></table></div></figure>


<p>A forma <strong>não</strong> recomendada:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'>    <span class="nc">Service</span><span class="p">[</span><span class="s1">&#39;httpd&#39;</span><span class="p">]</span> <span class="err">&lt;-</span> <span class="ss">Package</span><span class="err">[</span><span class="s1">&#39;httpd&#39;</span><span class="p">]</span>
</span><span class='line'>    <span class="ss">Service</span><span class="err">[</span><span class="s1">&#39;httpd&#39;</span><span class="p">]</span> <span class="err">&lt;~</span> <span class="ss">File</span><span class="err">[</span><span class="s1">&#39;httpdconf&#39;</span><span class="p">]</span>
</span></code></pre></td></tr></table></div></figure>


<p>Quando possível, utilize meta-parâmetros ao invés de relacionamento interno.</p>

<h3>9.4 Classes internas</h3>

<p>No início já falamos disto, devemos evitar criar classes dentro de classes, ou mesmo definições dentro de classes.</p>

<p>A forma <strong>não</strong> recomendada:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'>    <span class="kd">class</span> <span class="nc">apache</span> <span class="p">{</span>
</span><span class='line'>      <span class="kd">class</span> <span class="nc">ssl</span> <span class="p">{</span> <span class="err">...</span> }
</span><span class='line'>    }
</span></code></pre></td></tr></table></div></figure>


<p>Outra forma <strong>não</strong> recomendada:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'>    <span class="kd">class</span> <span class="nc">apache</span> <span class="p">{</span>
</span><span class='line'>      <span class="kd">define</span> <span class="nc">config</span><span class="p">()</span> <span class="p">{</span> <span class="err">...</span> }
</span><span class='line'>    }
</span></code></pre></td></tr></table></div></figure>


<p>Prefira sempre criar um arquivo separado e declarar uma única classe ou uma única definição neste arquivo.</p>

<h3>9.5 Classes e herança</h3>

<p>Herança pode ser usada em módulos, mas deve ser utilizada entre as classes do módulo. Se o seu objetivo é  herdar uma classe de outro módulo, pense em usar o <strong>include</strong> ao invés do <strong>inherits</strong>. O simples ato de fazer herança entre módulos já viola o proprio conceito de modularidade, evite isto ao máximo.</p>

<p>A forma <strong>certa</strong> de fazer:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'>    <span class="kd">class</span> <span class="nc">ssh</span> <span class="p">{</span> <span class="err">...</span> }
</span><span class='line'>
</span><span class='line'>    <span class="kd">class</span> <span class="nc">ssh::client</span> <span class="kd">inherits</span> <span class="nc">ssh</span> <span class="p">{</span> <span class="err">...</span> }
</span><span class='line'>
</span><span class='line'>    <span class="kd">class</span> <span class="nc">ssh::server</span> <span class="kd">inherits</span> <span class="nc">ssh</span> <span class="p">{</span> <span class="err">...</span> }
</span><span class='line'>
</span><span class='line'>    <span class="kd">class</span> <span class="nc">ssh::server::solaris</span> <span class="kd">inherits</span> <span class="nc">ssh::server</span> <span class="p">{</span> <span class="err">...</span> }
</span></code></pre></td></tr></table></div></figure>


<p>A forma <strong>não</strong> recomendada:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'>    <span class="kd">class</span> <span class="nc">ssh</span> <span class="kd">inherits</span> <span class="nc">server</span> <span class="p">{</span> <span class="err">...</span> }
</span><span class='line'>
</span><span class='line'>    <span class="kd">class</span> <span class="nc">ssh::client</span> <span class="kd">inherits</span> <span class="nc">workstation</span> <span class="p">{</span> <span class="err">...</span> }
</span><span class='line'>
</span><span class='line'>    <span class="kd">class</span> <span class="nc">wordpress</span> <span class="kd">inherits</span> <span class="nc">apache</span> <span class="p">{</span> <span class="err">...</span> }
</span></code></pre></td></tr></table></div></figure>


<h3>9.6 Variáveis e namespace</h3>

<p>Quando usarmos váriaveis de topo de escopo ou fatos, devemos declará-las de forma a evitar carregamento de uma variável com o mesmo nome
mas em escopo local.</p>

<p>A forma <strong>certa</strong> de fazer:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="nv">$::operatingsystem</span>
</span></code></pre></td></tr></table></div></figure>


<p>A forma <strong>não</strong> recomendada:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="nv">$operatingsystem</span>
</span></code></pre></td></tr></table></div></figure>


<p>Se não fizermos isto e houver uma variável com o mesmo nome em escopo
local, ou seja, se você por alguma razão criou uma variável em um
manifest do seu módulo com o nome <strong>operatingsystem</strong>, por ordem
de precedência a variável de escopo <strong>local</strong> será carregada e não a  variável - ou fato - de topo de escopo, desta forma seu código pode ter um comportamento indesejado.</p>

<h3>9.7 Nome de variáveis</h3>

<p>Quando for definir variáveis, procure usar apenas letras, números
e underscore. Não use hífen ou travessão.</p>

<p>A forma <strong>certa</strong> de fazer:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="nv">$foo_bar123</span>
</span></code></pre></td></tr></table></div></figure>


<p>A forma <strong>não</strong> recomendada:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="nv">$foo</span><span class="o">-</span><span class="ss">bar123</span>
</span></code></pre></td></tr></table></div></figure>


<h3>9.8 Classes e Parâmetros</h3>

<p>Em classes parametrizadas e definições, devemos tomar um cuidado especial na hora da declaração. Parâmetros obrigatórios devem ser listados antes de parâmetros opcionais.</p>

<p>A forma <strong>certa</strong> de fazer:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'>    <span class="kd">class</span> <span class="nc">ntp</span> <span class="p">(</span>
</span><span class='line'>    <span class="nv">$servers</span><span class="p">,</span>
</span><span class='line'>    <span class="nv">$options</span>   <span class="p">=</span> <span class="s2">&quot;iburst&quot;</span><span class="p">,</span>
</span><span class='line'>    <span class="nv">$multicast</span> <span class="p">=</span> <span class="ss">false</span>
</span><span class='line'>    <span class="p">)</span> <span class="p">{</span>}
</span></code></pre></td></tr></table></div></figure>


<p>A forma <strong>não</strong> recomendada:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="kd">class</span> <span class="nc">ntp</span> <span class="p">(</span>
</span><span class='line'>    <span class="nv">$options</span>   <span class="p">=</span> <span class="s2">&quot;iburst&quot;</span><span class="p">,</span>
</span><span class='line'>    <span class="nv">$servers</span><span class="p">,</span>
</span><span class='line'>    <span class="nv">$multicast</span> <span class="p">=</span> <span class="ss">false</span>
</span><span class='line'>    <span class="p">)</span> <span class="p">{</span>}
</span></code></pre></td></tr></table></div></figure>


<h2>10. Testes</h2>

<p>Todos os manifests de um módulo devem ter um manifest de teste no diretório tests, isso é chamado de smoking test, o objetivo do
smoking test é demonstrar como uma classe ou definição deve
ser declarada.</p>

<p>exemplo de manifest:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="c-Singleline"># /etc/puppet/modules/ntp/manifests/init.pp</span>
</span><span class='line'><span class="kd">class</span> <span class="nc">ntp</span> <span class="p">{</span>
</span><span class='line'>    <span class="nc">package</span> <span class="p">{</span> <span class="s1">&#39;ntp&#39;</span><span class="p">:</span>
</span><span class='line'>        <span class="nt">ensure</span> <span class="p">=&gt;</span> <span class="ss">present</span><span class="p">,</span>
</span><span class='line'>    <span class="p">}</span>
</span><span class='line'>}
</span></code></pre></td></tr></table></div></figure>


<p>exemplo de smoking test:</p>

<figure class='code'> <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class='puppet'><span class='line'><span class="c-Singleline"># /etc/puppet/modules/ntp/tests/init.pp</span>
</span><span class='line'><span class="nc">class</span> <span class="p">{</span> <span class="ss">ntp</span><span class="p">:</span> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<h2>11. Puppet DOC</h2>

<p>O Puppet Doc é um recurso que nos permite documentar nossas classes e definições utilizando RDoc markup. Esse documentação inline é
importante para facilitar a geração de documentação online, isto
significa que uma vez gerada, poderá ser extraída pelo própio puppet
doc quando desejar informações e comentários das classes e definções
de seu módulo.</p>

<p>Modelo para classes:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
</pre></td><td class='code'><pre><code class=''><span class='line'># == Class: example_class
</span><span class='line'>#
</span><span class='line'># Full description of class example_class here.
</span><span class='line'>#
</span><span class='line'># === Parameters
</span><span class='line'>#
</span><span class='line'># Document parameters here.
</span><span class='line'>#
</span><span class='line'># [*ntp_servers*]
</span><span class='line'>#   Explanation of what this parameter affects and what it defaults to.
</span><span class='line'>#   e.g. "Specify one or more upstream ntp servers as an array."
</span><span class='line'>#
</span><span class='line'># === Variables
</span><span class='line'>#
</span><span class='line'># Here you should define a list of variables that this module would require.
</span><span class='line'>#
</span><span class='line'># [*enc_ntp_servers*]
</span><span class='line'>#   Explanation of how this variable affects the funtion of this class and if it
</span><span class='line'>#   has a default. e.g. "The parameter enc_ntp_servers must be set by the
</span><span class='line'>#   External Node Classifier as a comma separated list of hostnames." (Note,
</span><span class='line'>#   global variables should not be used in preference to class parameters  as of
</span><span class='line'>#   Puppet 2.6.)
</span><span class='line'>#
</span><span class='line'># === Examples
</span><span class='line'>#
</span><span class='line'>#  class { 'example_class':
</span><span class='line'>#    ntp_servers =&gt; [ 'pool.ntp.org', 'ntp.local.company.com' ]
</span><span class='line'>#  }
</span><span class='line'>#
</span><span class='line'># === Authors
</span><span class='line'>#
</span><span class='line'># Author Name &lt;author@example.com&gt;
</span><span class='line'>#
</span><span class='line'># === Copyright
</span><span class='line'>#
</span><span class='line'># Copyright 2011 Your name here, unless otherwise noted.
</span><span class='line'>#
</span><span class='line'>class example_class {
</span><span class='line'>
</span><span class='line'>}
</span></code></pre></td></tr></table></div></figure>


<p>Modelo para definições:</p>

<p>&#8220;`</p>

<pre><code># == Define: example_resource
#
# Full description of defined resource type example_resource here.
#
# === Parameters
#
# Document parameters here
#
# [*namevar*]
#   If there is a parameter that defaults to the value of the title string
#   when not explicitly set, you must always say so.  This parameter can be
#   referred to as a "namevar," since it's functionally equivalent to the
#   namevar of a core resource type.
#
# [*basedir*]
#   Description of this variable.  For example, "This parameter sets the
#   base directory for this resource type.  It should not contain a trailing
#   slash."
#
# === Examples
#
# Provide some examples on how to use this type:
#
#   example_class::example_resource { 'namevar':
#     basedir =&gt; '/tmp/src',
#   }
#
# === Authors
#
# Author Name &lt;author@example.com&gt;
#
# === Copyright
#
# Copyright 2011 Your name here, unless otherwise noted.
#
define example_class::example_resource($basedir) {

}
</code></pre>

<p> &#8220;`</p>

<p>[s]<br>
Guto</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Cloud Magic APP]]></title>
    <link href="http://gutocarvalho.net/octopress/2013/04/19/cloud-magic-app/"/>
    <updated>2013-04-19T14:29:00-03:00</updated>
    <id>http://gutocarvalho.net/octopress/2013/04/19/cloud-magic-app</id>
    <content type="html"><![CDATA[<p>Há alguns dias encontrei essa ferramenta pesquisando soluções para sincronizar os contatos do IOS com os contados do Android. Ela não estava relacionada com minha necessidade, porém, como fiquei curioso para ver como funcionava, instalei no celular e logo depois no meu navegador Chrome.</p>

<p>A proposta da ferramenta é simples, ela indexa suas mensagens de correio do gmail, posts no twitter, status do facebook, dados de arquivos no dropbox, google drive, evernote, dentre outros, e te permite fazer uma busca simples e eficiente de todo o seu conteúdo em nuvem.</p>

<p>Percebi que essa ferramenta ajuda a resolver algumas situações importantes, são elas:</p>

<p>1) Quando você não se lembre exatamente quando você postou um link sobre algum assunto no Facebook ou outra rede social, mas precisa encontrar essa informação.</p>

<p>2) Quando você não consegue encontrar aquele e-mail que você mandou para alguém, o qual havia uma informação importante, porém você se lembra de ter tocado no mesmo assunto em alguma rede social e gostaria de combinar a pesquisa, extrapolando o gmail.</p>

<p>3) Quando alguém disse que você postou algo sobre um assunto mas você não se lembra se foi no twitter, facebook ou por e-mail, e gostaria de rever esse seu post.</p>

<p>Aqui apresentei apenas três situações que já me ocorreram e foram resolvidas usando o CloudMagic.</p>

<p>Atualmente ele consegue pesquisar em muitas redes sociais e serviços CLOUD, abaixo alguns exemplos:</p>

<ul>
<li>GMAIL</li>
<li>GTALK</li>
<li>EVERNOTE</li>
<li>DROPBOX</li>
<li>GOOGLE DRIVE</li>
<li>GOOGLE APPS</li>
<li>FACEBOOK</li>
<li>TWITTER</li>
<li>ICLOUD</li>
<li>EXCHANGE</li>
<li>HOTMAIL</li>
<li>MSN</li>
</ul>


<p>Além destas, existem outras redes, acesse o site do <a href="https://cloudmagic.com/k/faq">cloudmagic</a> para saber mais.</p>

<p>Veja abaixo um vídeo que explica melhor o funcionamento da ferramenta.</p>

<iframe width="560" height="315" src="http://www.youtube.com/embed/F1tH-S2HjGg" frameborder="0" allowfullscreen></iframe>


<p>A ferramenta é bacana, recomendo.</p>

<p>Até 50 pesquisas por mês é de graça, acima disto custa U$ 4.99 por mês.</p>

<p>Para todas aquelas pessoas que trabalham diariamente em redes sociais (analistas/jornalistas/blogueiros/micro-bloqueiros), esta parece ser uma ferramenta muito eficiente ao preço de um cafezinho expresso por mês.</p>

<p>Fica a dica!</p>

<p>[s]<br>
Guto</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[DevOpsDays Brasil 2013]]></title>
    <link href="http://gutocarvalho.net/octopress/2013/04/18/devopsdays-brasil-2013/"/>
    <updated>2013-04-18T09:33:00-03:00</updated>
    <id>http://gutocarvalho.net/octopress/2013/04/18/devopsdays-brasil-2013</id>
    <content type="html"><![CDATA[<p><img class="right" src="http://gutocarvalho.net/octopress/images/posts/2013-04-18/devopsdays.png" title="[DevOps Days Logo]" ></p>

<p>Tenho o prazer de anunciar que vamos receber o evento DevOpsDays no Brasil em 2013, o evento irá acontecer no dia 17 de Agosto, a cidade escolhida desta vez foi o Rio de Janeiro.</p>

<p>A <a href="http://devopsdays.org/events/2013-brazil/propose/">chamada de trabalhos</a> está aberta, envie suas propostas, eu já enviei as minhas :)</p>

<p>O Brasil já recebeu este evento em 2010 em São Paulo, agora novamente teremos a oportunidade de trocar experiências sobre a cultura DevOPs.</p>

<p>Para maiores informações acesse o site <a href="http://www.devopsdays.org">devopsdays</a> e o <a href="http://www.devopsdays.org/blog">blog</a> do evento.</p>

<p>Se você não sabe o que significa devops e não conhece este evento, acompanhe o post que eu escrevi explicando o que é <a href="http://gutocarvalho.net/octopress/2013/03/16/o-que-e-um-devops-afinal/">devops</a> para entender melhor o termo e o evento em si.</p>

<p>[s]<br>
Guto</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Vale a pena usar o Puppet em infra pequena?]]></title>
    <link href="http://gutocarvalho.net/octopress/2013/04/17/vale-a-pena-usar-o-puppet-em-infra-pequena/"/>
    <updated>2013-04-17T11:51:00-03:00</updated>
    <id>http://gutocarvalho.net/octopress/2013/04/17/vale-a-pena-usar-o-puppet-em-infra-pequena</id>
    <content type="html"><![CDATA[<p><img class="right" src="http://gutocarvalho.net/octopress/images/posts/duvidas.png" title="[Duvidas]" ></p>

<p>Hoje eu recebi um e-mail em que me fora perguntado se valia a pena usar o Puppet
em infra pequena. Esta mesma pessoa mencionou que administra uma infra com
cerca e 4 servidores LINUX. Para conseguir responder este tipo de questionamento
eu faço sempre uma reflexão e me pergunto quanto vale <strong>o meu tempo</strong>.</p>

<p>No meu caso, meu tempo é precioso, com ele posso fazer coisas maravilhosas,
posso estudar, posso pesquisar, posso testar novas tecnologias, posso documentar,
posso ensinar, posso executar projetos e além disso posso ter um tempo de
qualidade com minha família, portanto, o meu tempo vale muito.</p>

<p>Sabendo que meu tempo vale muito, e principalmente sabendo que ele pode ser aproveitado
de diversas formas interessantes - como mencionei acima, penso que investir cerca de 3 a 4 horas
deste tempo para preparar um destes 4 servidores, executando tarefas repetitivas
e manuais, não é realmente a melhor forma de aproveitá-lo.</p>

<p>Ao usar o Puppet, mesmo em uma infra pequena, eu conseguirei investir só o que é realmente
necessário para aquela tarefa, e farei isso de forma ágil. Ao invés de
consumir horas e as vezes dias do meu precioso tempo, eu consigo fazer a mesma
tarefa poucos em minutos e poderei utilizar o tempo restante para outras atividades.</p>

<blockquote><p>É importante entender que além da diminuição de tempo investido em atividades cotidianas, o uso do puppet oferece um maior controle do meu parque, me permite padronizar meus servidores, me permite automatizar atividades e tarefas, me oferece garantia de integridade de minhas configurações, me permite controlar mudanças de forma ágil e segura, principalmente se for um ambiente crítico. O Puppet me ajuda a diminuir o índice de falhas e incidentes, tornando meus ambientes mais disponíveis e estáveis, não importando se eu tenho 4 ou 4 mil máquinas.</p></blockquote>


<p>Portanto, seu o seu tempo também é precioso, o Puppet é a ferramenta ideal para você recuperá-lo,  permitindo inclusive que você passe a agregar valor ao seu negócio e a sua vida, além de deixar seu ambiente muito mais eficiente, ágil e estável.</p>

<p>[s]<br>
Guto</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Mailbox APP]]></title>
    <link href="http://gutocarvalho.net/octopress/2013/04/17/mailbox-app/"/>
    <updated>2013-04-17T11:33:00-03:00</updated>
    <id>http://gutocarvalho.net/octopress/2013/04/17/mailbox-app</id>
    <content type="html"><![CDATA[<p>Há algumas semanas vi um vídeo no site &#8220;The Verge&#8221;&#8221; sobre esse novo APP de correio - específico para GMAIL - chamado Mailbox, a nova aplicação fez tanto sucesso que o Dropbox comprou a empresa sem pensar duas vezes.</p>

<p>Quando instalei esta APP, entrei em uma fila para ativação, parece que a procura foi tão grande que eles tiveram que liberar o uso aos poucos para não sobrecarregar sua infra.</p>

<p>Em apenas seis semanas após o lançamento eles atingiram a marca de 1 milhão de contas de e-mail configuradas, algo respeitável.</p>

<p>Ontem especificamente percebi que a APP estava liberada para uso, comecei a usar e confesso que gostei da forma proposta pela APP para processar as mensagens, esta APP torna possível zerar sua inbox diariamente, fica a dica.</p>

<p>Veja o vídeo de divulgação do MailApp</p>

<iframe width="560" height="315" src="http://www.youtube.com/embed/CICMxwgm274" frameborder="0" allowfullscreen></iframe>


<p>Veja o vídeo &#8220;Hands On&#8221; do pessoal do site &#8220;The Verge&#8221;.</p>

<iframe width="560" height="315" src="http://www.youtube.com/embed/FG-h8pDXfoE" frameborder="0" allowfullscreen></iframe>


<p>Para quem estava triste com o fim o Sparrow, parece que o MailApp é um bom substituto para o IOS.</p>

<p>Acesse o blog deles para saber mais => <a href="http://www.mailboxapp.com/blog/">http://www.mailboxapp.com/blog/</a></p>

<p>A aplicação é FREE e não há mais fila de espera.</p>

<p>[s]<br>
Guto</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Sincronizando contatos entre IOS e Android]]></title>
    <link href="http://gutocarvalho.net/octopress/2013/04/17/sincronizando-contatos-entre-ios-e-android/"/>
    <updated>2013-04-17T09:17:00-03:00</updated>
    <id>http://gutocarvalho.net/octopress/2013/04/17/sincronizando-contatos-entre-ios-e-android</id>
    <content type="html"><![CDATA[<p>Eu uso dois celulares, um iphone 4 (trabalho) e um android S3 (pessoal), desde de 2010 sou usuário apple e sincronizo meus contatos e todo o restante via icloud, porém ao pegar o segundo celular (S3) fiquei com uma grande dificuldade de sincronizar os contatos entre IOS e Android.</p>

<p>No Macbook eu instalei o KIES que é o software da SAMSUNG para sincronizar contatos, agenda e afins entre OSX e Android, porém, o KIES funciona de forma bem instável no OSX, além disto, ele só puxa as coisas do OSX para o Android e não manda as coisas do Android para o OSX, ou seja, crei um contato no S3, terei que criar na mão no OSX para que depois ele apareça no iphone via icloud.</p>

<p>Era uma situação bem chata e ficou ainda mais difícil quando coloquei uma ROM personalizada no S3 (cyanogenmod), a partir daí o KIES não reconhece mais seu celular.</p>

<p>Estava quase retornando para a STOCK ROM (firmware do fabricante) quando pesquisando na Google Play achei um software sensacional para resolver este
problema.</p>

<p>O Software chama-se &#8221;<a href="http://bit.ly/15lVgcB">SmoothSync for Cloud Contacts</a>&#8221;, ele foi escrito por Martin Gajda. Este software permite two-way-sync entre seu Android e iCloud. Sincronizar utilizando este método (two-way-sync), significa que se eu criar algo no Android ele vai aparecer no IOS, se eu criar algo no IOS ele vai aparecer no Android.</p>

<p>O software é pago, custa o equivalente a um café expresso com um pão de queijo, logo, na minha opinião compensa muito, comprei e recomendo.</p>

<p>[s]<br>
Guto</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How linux is built]]></title>
    <link href="http://gutocarvalho.net/octopress/2013/04/17/how-linux-is-built/"/>
    <updated>2013-04-17T08:53:00-03:00</updated>
    <id>http://gutocarvalho.net/octopress/2013/04/17/how-linux-is-built</id>
    <content type="html"><![CDATA[<p>Eu vi este vídeo hoje (2013-04-17) no Google Plus, há muito tempo eu não encontrava algo sobre o Linux com dados realmente atualizados, parece que finalmente encontrei. Para quem ainda não conhece, ou mesmo para aqueles que querem saber mais sobre o alcance do linux, esse é um vídeo esclarecedor.</p>

<p>[s]<br>
Guto</p>

<iframe width="560" height="315" src="http://www.youtube.com/embed/yVpbFMhOAwE" frameborder="0" allowfullscreen></iframe>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[O que é DevOps afinal?]]></title>
    <link href="http://gutocarvalho.net/octopress/2013/03/16/o-que-e-um-devops-afinal/"/>
    <updated>2013-03-16T15:47:00-03:00</updated>
    <id>http://gutocarvalho.net/octopress/2013/03/16/o-que-e-um-devops-afinal</id>
    <content type="html"><![CDATA[<p><img src="http://gutocarvalho.net/octopress/images/posts/bluedevops.png" title="[Blue DevOps]" ></p>

<h2>1. Papo sobre DevOps</h2>

<p>Hoje vim falar sobre a buzzword <strong>DevOPs</strong>. Algumas pessoas tem me procurado pelo blog para conversar sobre este termo, e normalmente eles querem que eu responda as seguintes perguntas:</p>

<ol>
<li>O que significa DevOps?</li>
<li>DevOps é um movimento?</li>
<li>DevOps é uma filosofia, é um conceito ou uma cultura?</li>
<li>DevOps é uma metodologia?</li>
<li>DevOps é algum tipo de ambiente ou grupo de ferramentas ?</li>
<li>O especialista DevOps é um devel que entende de infra?</li>
<li>O especialista DevOps é um sysadmin que entende de devel?</li>
<li>DevOps é um cargo? é um setor ou um departamento?</li>
<li>DevOps só funciona em startups ou serve para o ambiente corporativo?</li>
<li>O DevOps é algo novo?</li>
</ol>


<p>Ao longo do texto eu pretendo responder a todas estas questões, mas para respondê-las vamos precisar entender algumas coisas antes.</p>

<h2>2. Como tudo começou?</h2>

<p>Para que possamos compreender de forma plena, precisamos ir ao cerne desta história. O movimento DevOPs não começou em um lugar só, existem muitos lugares que dão pistas sobre as origens do termo, mas aparentemente as informações mais <a href="http://itrevolution.com/the-convergence-of-devops/">concretas</a> sobre as origens deste movimento nos levam ao ano de 2008. Neste ano, começaram a utilizar o termo <strong>infraestrutura ágil</strong> em algumas listas de discussão com foco em desenvolvimento ágil, e na mesma época durante evento <strong>Agile 2008</strong>, surgiram conversas que abordavam o tema metodologia ágil para a administração de infraestrutura, inspirada no modelo ágil de desenvolvimento, no entanto, foi a lista de discussão européia com nome <strong>agile-sysadmin</strong> que começou a abordar o tema com propriedade, com isso ela ajudou a colocar os primeiros tijolos na ponte que faria a ligação entre developers e sysadmins. Um dos participantes desta lista era Patrick Debois (@patrickdebois), além de muito ativo ele era e ainda é um grande entusiasta do assunto.</p>

<p>O termo DevOPS só foi criado de fato em 2009 durante a conferência Velocity da O&#8217;Reilly, nesta conferência John Allspaw (Etsy.com) e Paul Hammond (Typekit) apresentaram o trabalho <strong>10+ Deploys Per Day: Dev and Ops Cooperation at Flickr</strong>, veja abaixo os slides desta palestra.</p>

<center><iframe src="http://www.slideshare.net/slideshow/embed_code/1628368?rel=0" width="597" height="486" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px" allowfullscreen webkitallowfullscreen mozallowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="http://www.slideshare.net/jallspaw/10-deploys-per-day-dev-and-ops-cooperation-at-flickr" title="10+ Deploys Per Day: Dev and Ops Cooperation at Flickr" target="_blank">10+ Deploys Per Day: Dev and Ops Cooperation at Flickr</a> </strong> from <strong><a href="http://www.slideshare.net/jallspaw" target="_blank">John Allspaw</a></strong> </div></center>


<br>


<p>A palestra acima deixou Patrick Debois muito animado, foi então que ele teve a ideia de criar um encontro chamado DevOpsDay, este encontro ocorreu em Ghent no final de 2009, foi um encontro de dois dias e aparentemente foi lá que tudo começou.</p>

<p>De lá para cá, Patrick Debois, Gildas Le Nadan, Andrew Clay Shafer, Kris Buytaert, JezzHumble, Lindsay Holmwood, John Willis, Chris Read, Julian Simpson, R.I.Piennar (mcollective) e muitos outros levaram o evento para diversas localidades, dentre elas:</p>

<ul>
<li>New York 2012</li>
<li>Rome 2012</li>
<li>Mountain View 2012</li>
<li>India 2012</li>
<li>Tokyo 2012</li>
<li>Austin 2012</li>
<li>Goteborg 2011</li>
<li>Bangalore 2011</li>
<li>Melbourne 2011</li>
<li>Mountain View 2011</li>
<li>Boston 2011</li>
<li>Göteborg 2011</li>
<li>Sao Paulo 2010</li>
<li>Hamburg 2010</li>
<li>Mountain View 2010 (video intro)</li>
<li>Sydney 2010</li>
<li>Ghent 2009</li>
</ul>


<p>É importante falar que ao levar o evento para diversos países, estas pessoas foram responsáveis por disseminar
a cultura DevOps pelo globo, com isso, direta ou indiretamente eles se tornaram a força motriz de uma discreta revolução
no mundo da TI.</p>

<p>Inicialmente a cultura DevOps se mostrou muito presente no ambiente das startups,  porém, algum tempo depois começou a fazer parte do mundo corporativo, aqui neste texto procuro trazer a visão da cultura DevOps no meio corporativo.</p>

<p>Na abertura do evento DevOpsDay há sempre um vídeo de intro, veja dois deles:</p>

<p>Ghent 2009</p>

<iframe width="420" height="315" src="http://www.youtube.com/embed/EOveXZhJpr4" frameborder="0" allowfullscreen></iframe>


<p>Mountain View 2010</p>

<iframe width="560" height="315" src="http://www.youtube.com/embed/a0N2ugDwi5g" frameborder="0" allowfullscreen></iframe>


<h2>3. DevOps Manifest</h2>

<p>Apesar de terem organizado o DevOpsDays em diversos países, não foi estabelecido um manifesto para o assunto, logo existem muitas interpretações acerca deste termo.</p>

<p>Mas antes de argumentar acerca do possível conteúdo de um manifesto DevOps, primeiro temos que entender a dinâmica na relação entre as áreas de infraestrutura (infra) e desenvolvimento (devel).</p>

<h2>4. Analisando Infra e Devel</h2>

<p>Para entender melhor o que DevOps significa, precisamos então analisar de forma prática e direta a vida de sysadmins, desenvolvedores e o cotidiano destas áreas, eu espero que isto lhe ajude a compreender melhor o assunto adiante.</p>

<p>Vamos imaginar - hipoteticamente - uma empresa de comunicação que desenvolve aplicações web em sua maioria para portais de notícias, e em alguns casos também faz aplicações web internas (rh, financeiro, administrativo), nessa empresa o devel trabalha com PHP, PYTHON, RUBY e JAVA.</p>

<p>Para um melhor entendimento, considere as duas características abaixo como cotidianas nesta empresa fictícia:</p>

<ol>
<li><p>O Devel está começando a trabalhar com metodologias ágeis (pró-ativo, evolutivo e contínuo).</p></li>
<li><p>A Infra continua trabalhando no modelo tradicional de administração (manual, caótico e reativo).</p></li>
</ol>


<h3>4.1 Infra em foco</h3>

<p>A infra é composta em parte pelos sysadmins, estes rapazes e moças tem a missão de manter os sistemas funcionando, são eles que fazem os deploys e os rollbacks das aplicações do devel, é responsabilidade deles manter o ambiente de produção intacto.</p>

<p>Os sysadmins tem que rodar as aplicações, monitorar o funcionamento, a performance, avaliar e propor melhorias de forma a manter as aplicações sob seu cuidado a pleno vapor - rodando de forma rápida e estável, além disto, eles devem planejar as mudanças com cautela, tentando minimizar os riscos envolvidos.</p>

<p>Eles se preocupam com segurança, estabilidade e principalmente com o acordo de nível de serviço (SLA) de cada produto sob sua responsabilidade, esta preocupação é fundamental para o negócio.</p>

<p>Entenda que se uma aplicação parar de funcionar isto vai impactar no SLA, podendo significar perdas financeiras significativas relacionadas ao produto, afinal produto fora significa cliente insatisfeito e prejuízo, seja ele financeiro, seja ele institucional, e no caso da sustentação do produto, isto significa que a prestadora do serviço, neste caso a empregadora dos sysadmins, pode ser multada. De toda o jeito, o que ocorre de forma direta é diminuição do valor do negócio.</p>

<p>Em resumo, a infra (sysadmins) se preocupa em <strong>proteger o valor do négocio</strong>.</p>

<h3>4.2 Devel em foco</h3>

<p>O devel é composto em parte por desenvolvedores, estas moças e rapazes trabalham com lógica e criatividade, eles passam boa parte de seu tempo codificando soluções, e focam seu trabalho nos requisitos que o analista conseguiu mapear junto ao cliente.</p>

<p>Os desenvolvedores estão constantemente criando e aprimorando suas aplicações, com isto novas versões são criadas e precisam ser disponibilizadas, assim seus clientes poderão usufruir dos recursos solicitados.</p>

<p>Nova versão significa novo deploy, e caso ocorra algum problema, isto irá demandar um rollback, ambos procedimentos envolvem equipes de infra.</p>

<p>Em resumo, podemos dizer que o devel se preocupa em <strong>aumentar o valor do negócio</strong>.</p>

<h3>4.3 Onde está o conflito?</h3>

<p><img src="http://gutocarvalho.net/octopress/images/posts/relacao-infra-devel.png" title="[Relação Infra e Devel]" ></p>

<p>Os desenvolvedores querem colocar suas aplicações no ar o mais rápido possível, no entanto os sysadmins querem ter certeza que a aplicação está
estável o suficiente para entrar em produção sem gerar incidentes.</p>

<p>Nos últimos anos esse conflito foi latente no mundo de TI, algumas empresas tinham regras tão rígidas que só permitiam deploy uma vez por semana - em casos mais rígidos apenas uma vez por mês, tudo isto pensando em proteger o negócio.</p>

<p>Com o devel mudando de metogologia, nem preciso dizer que esse método de deploy - uma vez por semana - não combina com desenvolvimento ágil, com isso a infra teve que evoluir a fórceps, e quem antes fazia deploy uma vez por semana, teve que aprender a fazer várias vezes por dia.</p>

<p>É claro que a infra trabalhando com os métodos que estava acostumada (deploy 1 vez por semana e manual) não dava vazão as demandas, e também é óbvio que o devel não possuía uma infra adequada para fazer o desenvolvimento de forma contínua.</p>

<p>Além de tudo isso, normalmente o devel não conhece e não tem como prever aspectos importantes relativos a infra que fica de cara para o cliente, portanto, quando a aplicação vai para produção, normalmente ocorrem - constantes - pequenos incidentes que geram uma enorme perda de valor no negócio. Traduzindo, são aqueles ajustes na aplicação que precisam ser feitos de última hora pois o ambiente devel é completamente diferente da produção.</p>

<p>O cliente por sua vez reclama - com razão - e depois a gerência de TI ficava tentando encontrar o dono do problema (caça as bruxas), de um lado devel dizendo que infra é engessada, lenta e que não oferece um ambiente adequado para desenvolverem suas aplicações, do outro lado a infra dizendo que o devel faz código ruim e instável e que não é culpa deles se a aplicação não funciona.</p>

<p>Eu sou de infra há muitos anos, mas tenho que dizer que a infra devido a culturas arcaicas de administração, heranças do tempo dos mainframes, tem mais culpa no cartório neste cenário, porém o devel também tem seus problemas, afinal, como estão começando a aplicar métodos ágeis, ainda estão criando a cultura de execução de testes e garantia de qualidade (QA).</p>

<h4>4.3.1 Incidentes</h4>

<p>Quando ocorre algum incidente, você vai ouvir da infra falando para o devel que <strong>o problema não são as máquinas, é o código</strong>, e certamente o devel vai falar para infra que <strong>o problema não é o código, são as máquinas</strong>, e provavelmente ainda vão dizer que o sistema <strong>está funcionando no  notebook deles</strong>, e infelizmente isso será algo cotidiano.</p>

<p><img class="right" src="http://gutocarvalho.net/octopress/images/posts/opsburn.png" title="[Ops Burn]" ></p>

<p>Espero que neste ponto você já esteja enxergando o problema.</p>

<p>É preciso entender que infra e o devel trabalham em nichos, cada um no seu quadrado, cada um em sua realidade e nenhum deles está muito disposto a mudar sua cultura, nenhum deles está disposto a ceder. A infra não conhece o devel e não sabe como mudar para ajudá-los, o devel não conhece a infra e não sabe como pedir o que precisam.</p>

<p>No final das contas, as pessoas não conseguem estabelecer uma forma sadia e eficiente de comunicação, e com isso, não existe trabalho colaborativo entre estas duas áreas.</p>

<h3>4.4 O combustível do conflito</h3>

<p><img src="http://gutocarvalho.net/octopress/images/posts/no.png" title="[Combustivel do Conflito No]" ></p>

<p>Acima eu apresentei o conflito comum entre as áreas, porém existe o combustível que o mantém acesso, e esse combustível é o comportamento do sysadmin, portanto, há de fato uma razão para se ter tanto ódio deles, vamos a elas:</p>

<ul>
<li>Eles falam não</li>
<li>Eles falam não pela segunda vez</li>
<li>Eles falam não pela terceira vez</li>
<li>Eles falam não o tempo todo por diversas razões, para diversos pedidos</li>
<li>Eles demoram, atrasam e perdem prazos de atendimento</li>
<li>Eles se recusam a quebrar as coisas mesmo que seja para encontrar o problema</li>
<li>Eles se preocupam com UPTIME e não com o negócio</li>
<li>Eles acham que o devel só quer saber de perfumarias e coisas do gênero</li>
<li>Eles não se esforçam para ajudar o devel a encontrar o problema</li>
<li>Eles acham que o problema do devel não é problema deles</li>
<li>Eles não conseguem enxergar o negócio e não enxergam que infra e devel são parte de um todo</li>
</ul>


<p>E isso tudo faz parte daquele comportamento arcaico que eu já mencionei, eu quis reforçar isto pois é bom mostrar as raizes de um problema para ajudar na reflexão do que é preciso mudar.</p>

<p>Veja que tal comportamento é inaceitável e incompatível com o mundo de hoje, mesmo assim ainda é muito comum encontrar pessoas que possuem este
tipo de atitude e perfil.</p>

<h3>4.5 Uma pitada de realidade</h3>

<p>Lembra que eu disse que a infra se preocupa em <strong>proteger o negócio</strong> e o devel se preocupa com as <strong>formas de agregar valor ao negócio</strong>?</p>

<p>Esqueça o que eu disse, isso funcionava nos anos 70/80/90, mas hoje isso não é suficiente.</p>

<p>A infra deve entender que sua obrigação é oferecer os meios para fazer o negócio fluir, e isso também é papel do devel.</p>

<p>Ambas equipes precisam mudar a forma de pensar e de agir, porém é preciso ter consciência de que mudanças estão associadas a problemas, uma mudança pode quebrar seu produto e afetar o seu negócio.</p>

<p>Então qual é a receita mágica?</p>

<p>Como mudar sem afetar o negócio?</p>

<h3>4.6 Mudanças necessárias</h3>

<p>A infra previsa evoluir, e precisa fazer isto rapidamente.</p>

<p>O devel predisa ter controle de todas as fases do deploy.</p>

<p>A infra precisa começar a trabalhar de forma automatizada e dinâmica, precisa ser mais veloz para subir novos ambientes ou mesmo reconstruir/duplicar os ambientes existentes para suprir as necessidades do devel, não dá mais para trabalhar de forma manual e usar as mesmas metodologias da época dos mainframes.</p>

<p>O devel precisa conseguir passar para infra suas necessidades de forma clara, e tem que se esforçar para fazer a infra entender isto - e eles não vão entender na primeira vez.</p>

<h3>4.6.1 Busca de soluções</h3>

<p>E foi a busca de soluções para estas necessidades que motivou importantes discussões no mundo da TI, foi então que começaram a falar de &#8216;Infraesturura ágil&#8217; no ano de 2008, vamos agora entender o que é isso.</p>

<h2>5. Infraestrutura ágil</h2>

<h3>5.1 Infraestrutua como código</h3>

<p>A discussão acerca de infraestrutura ágil ganhou força com o crescimento de duas tendências, são elas <strong>virtualization</strong> e <strong>cloud computing</strong>. Desde 2003 empresas começaram a conviver com ambientes virtualizados, logo um parque com poucas máquinas físicas poderia se tornar um parque com dezenas máquinas virtuais, e após o recente  advento da Cloud, dezenas de máquinas virtuais podem se tornar centenas ou milhares de instâncias a serem administradas na nuvem.</p>

<p>Não havia mais espaço para se trabalhar infraestrutrua da forma tradicional, foi necessário dar um passo a diante e pensar em infraestrutura como código, principalmente quando paramos para analisar o recente boom das startups, empresas pequenas com produtos de enorme alcance, produtos que rodam em centenas de instâncias na nuvem, atendendo milhões de usuários, e tudo isso é administrado por equipes mínimas.</p>

<p>O objetivo é fazer deploy não só de aplicações, mas deploy de infraestrutura de forma rápida e controlada.</p>

<p>Isso significa que se você precisa subir um ambiente JBOSS você vai fazer isto em poucos minutos e não em dias.</p>

<h3>5.2 Ferramentas de infraestrutura ágil</h3>

<p>Quando se fala em infraestrutura ágil o que vem a mente são ferramentas, e de fato elas são parte disto.</p>

<p>Basicamente temos três tipos de ferramentas, são elas:</p>

<ol>
<li>Orquestradores</li>
<li>Ferramentas para gerenciamento de configurações</li>
<li>Ferramentas para bootstrapping e provisionamento</li>
</ol>


<p>Orquestradores são ferramentas que nos permitem executar comandos e controlar nodes/instâncias de nosso parque em tempo real. Alguns destes são Fabric,
Capistano, Func e Mcollective.</p>

<p>Ferramentas de gerência de configuração normalmente controlam estados de seu sistema, ajudam a centralizar toda as configurações e facilitam a administração e criação de novos ambientes. Algumas delas são Puppet, Chef, Cfegine e Salt.</p>

<p>Ferramentas de bootstrapping são aquelas que nos ajudam a instalar um sistema operacional seja em uma máquina física, seja em um máquina virtual, seja em uma instância na nuvem, dentre elas temos alguns provedores de CLOUD como AWS e Rackspace que já oferecem isso nativamente, existem também ferramentas como o Kickstart e Cobbler que atuam neste segmento.</p>

<p>A combinação destes três tipos de ferramentas nos permite ter o que chamamos de infraestrutura ágil.</p>

<p>Mas apesar da qualidade e dos ganhos em utilizar tais tecnologias, a ferramenta sozinha não resolverá seus problemas, é preciso mudar a cultura e a forma de trabalhar a infraestrutura.</p>

<h3>5.3 Equipe de infraestrutura ágil</h3>

<p>Equipes que trabalham com infraestrutura ágil também precisam de um método diferenciado de organização, normalmente estas equipes estão trabalhando seguindo estes eixos:</p>

<ol>
<li>Versionamento do código e arquivos de configuração (git)</li>
<li>Organização de atividades de forma visual (KANBAN BOARD)</li>
<li>Trabalho em pares</li>
<li>Divisão das atividades em sprints</li>
<li>Reuniões ágeis diárias (standup meeting de 10 minutos - em pé)</li>
<li>Reuniões ágeis periódicas (retrospectiva e planejamento de sprints).</li>
</ol>


<p>Parece com SCRUM mas não é, mas é fortemente inspirado nele e no Kanban.</p>

<h3>5.4 Então DevOps e Infraestrutura ágil são a mesma coisa?</h3>

<p>Não, infraestrutura ágil é parte da cultura DevOps.</p>

<p>DevOps depende de infraestutura ágil, mas ainda tem muito mais.</p>

<p>Apesar da evolução da infra, ainda falta algo que conecte as duas áreas, precisamos de um agente de mudanças principalmente
no meio corporativo.</p>

<h2>6. Cultura DevOps</h2>

<p>Chegou a hora de entrar neste assunto, agora nós vamos aprofundar nossos estudos em relação a cultura DevOps.</p>

<h3>6.1 Características da cultura DevOps</h3>

<p>Para entender a cultura devops sem fazer um texto muito longo, vou pontuar as suas principais características - em minha opinião.</p>

<h4>6.1.1 Em relação as características da cultura</h4>

<p>Patrick Debois (foi quem cunhou o termo) diz que DevOPs essencialmente é uma cultura, e a descreve utilizando 4 eixos, são eles:</p>

<ul>
<li>Cultura

<ul>
<li>Colaboração</li>
<li>Fim das divisões</li>
<li>Relação saudável entre as áreas</li>
<li>Mudança de comportamento</li>
</ul>
</li>
<li>Automação

<ul>
<li>Deploy</li>
<li>Controle</li>
<li>Monitoração</li>
<li>Gerência de configuração</li>
<li>Orquestração</li>
</ul>
</li>
<li>Avaliação

<ul>
<li>Métricas</li>
<li>Medições</li>
<li>Performance</li>
<li>Logs e integração</li>
</ul>
</li>
<li>Compartilhamento

<ul>
<li>O feedback é tudo</li>
<li>Boa comunicação entre a equipe</li>
</ul>
</li>
</ul>


<p>Eu prentendo detalhar um pouco mais estes eixos, vamos lá.</p>

<h4>6.1.2 Em relação as características técnicas</h4>

<p>Um ambiente DevOps deve ter/possuir/oferecer/permitir:</p>

<ul>
<li>Infraestrutura como código</li>
<li>Orquestração de servidores</li>
<li>Gerência de configurações</li>
<li>Provisionamento dinâmico de ambientes</li>
<li>Controle de versões compartilhado entre infra e devel</li>
<li>Ambiente de desenvolvimento, teste e produção (no mínimo)</li>
<li>O ambiente de devel deve possibilitar TDD</li>
<li>Infra deve participar dos projetos desde o início [1]</li>
<li>Infra deve participar das reuniões de devel [2]</li>
<li>Devel deve participar das reuniões de infra [3]</li>
<li>Ambiente de entrega contínua [4]</li>
<li>Os desenvolvedores devem conseguir fazer o deploy sem interferência da infra [5]</li>
<li>Monitoramento eficaz com processamento adequado dos eventos e métricas</li>
<li>Capacidade de resposta rápida a incidentes e problemas</li>
<li>Backup e restore confiável</li>
</ul>


<p>[1] O devel precisa envolver a infra nos projetos desde o início - isso significa participar das reuniões técnicas ou SCRUM, afinal sem a infra não há projeto, e além disto, quanto mais problemas foram resolvidos durante o projeto - com ajuda da infra, menos problemas serão expostos aos clientes.</p>

<p>[2] A infra também precisa observar quais são as metas da empresa a longo prazo, principalmente aquelas ligadas ao devel, pois enxergando onde o devel quer chegar, ela pode se programar melhor para ter certeza que a infraestrutura tecnológica estará preparada para atendê-los quando esse momento chegar.</p>

<p>[3] A infra precisa envolver o devel em suas reuniões técnicas para que o devel entenda e tenha ciência da realidade da infra, assim eles vão conseguir enxergar suas qualidades, atribuições, planos de melhorias, atualizações programadas, agendas de manutenção, eles vão conhecer os recursos disponíveis e também descobrir a limitações da equipe, sejam elas técnicas, sejam materiais. Além disto, o devel pode ser um grande aliado da infra na solução de problemas, afinal o conhecimento que o devel traz pode ajudá-los a melhorar a forma com que administram seu ambiente, tornando este processo mais eficiente.</p>

<p>[4] O devel precisa adotar alguma metodologia de entrega ou desenvolvimento contínuo e a infra precisa entender esse processo para que juntos criem os ambientes com as ferramentas certas.</p>

<p>[5] A infra precisa ceder um pouco e evoluir, precisa oferecer ao devel um ambiente adequado onde eles sejam o dono do produto, onde o devel consiga fazer todo o ciclo de desenvolvimento de forma direta, o devel precisa conseguir gerar e controlar o código, precisa fazer o commit com segurança, precisa fazer o build, testar o build, validar a aplicação e entregar a nova versão de forma transparente sem que para isso precise passar por um burocrático e engessado processo de mudança.</p>

<h4>6.1.3 Em relação aos valores humanos</h4>

<p>Para a adoção da cultura funcionar, a equipe precisa observar e exercitar os seguintes valores:</p>

<ul>
<li>Confiança no trabalho de sua equipe</li>
<li>Respeito pessoal e profissional por todos da equipe</li>
<li>Sinceridade sobre eventos e incidentes ocorridos</li>
<li>Honestidade sobre as causas dos incidentes (não esconda nada da sua equipe)</li>
<li>Entendimento de que o problema é responsabilidade de todos</li>
<li>Entendimento de a solução é responsabilidade de todos</li>
<li>Entendimento de que os resultados são o reflexo do trabalho de toda a equipe</li>
<li>Comunicação efetiva e dinâmica</li>
<li>Postura construtiva sempre</li>
<li>Espírito de colaboração</li>
</ul>


<h4>6.1.4 Em relação a forma de trabalho</h4>

<p>É recomendavél que a equipe:</p>

<ul>
<li>Internalize e adapte métodos ágeis como KABAN e SCRUM para seu dia-a-dia</li>
<li>Aprofunde estudos em entrega contínua</li>
<li>Aprofunde estudos em gerência de configurações e orquestração</li>
</ul>


<p>Acho que é isso, características técnicas, valores humanos e forma de trabalhar, espero que tenha ficado claro para você.</p>

<h3>6.2 Aplicando a cultura</h3>

<p>Após observar as principais características deste movimento, normalmente pensamos em como aplicar isto em nosso meio. Para
ajudar na reflexão vamos avaliar o meio startup e o meio corporativo.</p>

<h4>6.2.1 A realidade no ambiente startup</h4>

<p>A cultura DevOPs combina muito com startups, nestes locais normalmente já se trabalha desenvolvimento utilizando metologias
ágeis, foi inclusive neste nicho em que começaram a discutir infraestrutura ágil - a precursora do movimento devops,
portanto, as pessoas deste meio conseguem absorver os conceitos e a cultura DevOPs sem grandes dificuldades,
eles conseguem compreender os preceitos de colaboração e feedback pois já fazem isto em seu dia-a-dia.</p>

<p>Quem está uma startup não tem as amarras e vícios da coporação, este é um grande facilitador e não é necessário
nenhum tipo de intervenção para internalizar a cultura, a partir do estímulo de um líder as pessoas começarão
a estudar e aplicar DevOPs naturalmente.</p>

<p>Na startup normalmente não existe divisões, departamentos, todos trabalham juntos e isso também é um facilitador, afinal
não existem barreiras para se comunicar.</p>

<h4>6.2.2 A realidade no ambiente corporativo</h4>

<p>A corporação não funciona como a startup, lá existe burocracia e o uso vicioso de métodos ultrapassados, portanto
não bastará o estímulo da alta hieraquia para que equipes de infra e devel comecem a vivenciar a cultura DevOPs, neste tipo
de ambiente, em minha opinião pessoal e profissional, é necessário intervir cirurgicamente para conseguir internalizar
a cultura DevOps.</p>

<p>Em resumo, você precisa trazer alguém - de fora - que conhece DevOP para que esta pessoa passe a contaminar os demais.</p>

<p>Esse processo é lento, mas se o especialista tiver os meios e o apoio do alto escalão, mudanças fantásticas poderão ocorrer.</p>

<h3>6.3 O especialista DevOps no meio corporativo</h3>

<p>Ele foi trazido para atuar como um agente de mudanças, ele precisa contaminar as áreas e mostrar que a cultura DevOps funciona.</p>

<h4>6.3.1 Característica gerais de um especialista DevOps em 2013</h4>

<ul>
<li>Está na casa dos 30 anos ou mais</li>
<li>É um profissional sênior em infraestrutura</li>
<li>Tem um bom background em desenvolvimento</li>
<li>Tem um bom background em metodologias ágeis</li>
<li>Tem sólidos conhecimentos em soluções opensource e similares</li>
<li>Trabalha intensamente com automação e infraestrutura como código</li>
</ul>


<h4>6.3.2 Onde esse especialista atua?</h4>

<p>Este especialista em DevOps terá um pé na infra e outro no devel, em alguns casos também terá o pé na área de garantia de qualidade (QA).</p>

<p><img src="http://gutocarvalho.net/octopress/images/posts/devops.png" title="[DevOps]" ></p>

<p>Ele é a cola que faltava para unir infra, devel e qualidade.</p>

<h4>6.3.3 Como esse especialista atua?</h4>

<p>Ele será a ponte entre as áreas de infra e devel, ele conhece a infra a fundo e entede de forma ampla processos de desenvolvimento ágil.</p>

<h5>6.3.3.1 Pé no devel</h5>

<p>Ele participa dos projetos de desenvolvimento desde o seu nascimento, seu foco é oferecer os recursos para os
desenvolvedores trabalhem da forma mais eficiente, além disto, com sua ótica de infra ele toma todas as precauções para que os aspectos de segurança, monitoramento, eficiência e escalabilidade sejam observados desde o início do projeto.</p>

<p>O DevOps vai ainda estudar todo o processo de desenvolvimento e definir - em conjunto com o devel - as ferramentas que irão permitir um processo de desenvolvimento e entrega contínua. Após definir ele vai instalar e manter esse infra.</p>

<p>Alguns DevOps conseguem até avaliar o código do produto e enxergar problemas de performance, esse tipo de visão sistêmica e raciocínio rápido são diferencias importantes para uma entrega com mais qualidade.</p>

<h5>6.3.3.1 Pé na infra</h5>

<p>Na infra ele é o principal agente de mudanças, é ele que vai puxar a fila para iniciar a implantação de uma
infraestrutura ágil, ele domina as ferramentas de orquestração, gerência de configuração e provisionamento
e vai usar esse conhecimento para que a equipe passe a trabalhar a infraestrutura como código.</p>

<p>Este profissional também vai ajudá-los a mudar seu comportamento e cultura, ele vai orientá-los nos métodos
ágeis de execução de atividades, aqueles inspirados no SCRUM e KANBAN.</p>

<h3>6.4 Ele fica na infra ou no devel?</h3>

<p>Para internalizar DevOPs, normalmente estas barreiras não existem, infra e devel devem habitar o mesmo espaço, sem
paredes, sem divisórias, todos na mesma sala, isso é fundamental para extinguir os nichos e criar uma equipe mais unida e coesa.</p>

<p>Respondendo a pergunta, ele deve ficar junto com as duas equipes se for possível, esse é o melhor dos mundos.</p>

<p>Se não for possível ficarem todos juntos, o especialista deve se esforçar para interagir com as duas equipes diariamente.</p>

<p>Ele vai ser o agente de mudanças até que infra e devel comecem a entender e adotar a cultura de forma natural.</p>

<h2>7. Quais os ganhos em adotar a cultura DevOPs?</h2>

<p>Vamos avaliar dentro da ótica de cada área o que melhora com a adoção da cultura DevOPs.</p>

<h3>7.1 Ganhos para a infra</h3>

<ul>
<li>Infraestrutua como código (equipe para de administrar e passa a desenvolver a infra)</li>
<li>Infra mais eficiente e rápida usando métodos ágeis</li>
<li>Equipe de Infra mais organizada</li>
<li>Equipe de Infra se comunicando melhor</li>
<li>Infra fazendo mais em menos tempo com menos gente</li>
<li>Ambientes de  gerência de configuração, orquestração e provisionamento implantados</li>
<li>Deploys de infra (novos ambientes) mais rápidos e seguros => entrega rápida</li>
<li>Ambiente padronizado e sob-controle</li>
<li>Feedback rápido em todas as atividades de infra</li>
</ul>


<h3>7.2 Ganhos para o devel</h3>

<ul>
<li>Devel tem ambiente mais adequado para trabalhar (dev/teste/prod)</li>
<li>Devel passa a contar com ambiente de desenvolvimento contínuo</li>
<li>Devel passa a contar com testes automatizados</li>
<li>Deploys de apps (novas versões) mais rápidos e seguros => entrega rápida</li>
<li>Feedback rápido em todas as fases de desenvolvimento</li>
</ul>


<h3>7.3 Ganhos mútuos Infra/Devel</h3>

<ul>
<li>Acaba a divisão Infra vs Devel (acaba a guerra)</li>
<li>Infra participa dos projetos e acompanha de perto tudo o que acontece</li>
<li>Infra participando resulta em melhor planejamento do ambiente de produção</li>
<li>Infra participando resulta em monitoramento mais eficaz da aplicação</li>
<li>Devel começa a compreender melhor a infra e isso resulta em um produto melhor</li>
<li>Equipes trabalhando em conjunto para aumentar o valor do negócio</li>
</ul>


<h3>7.4 Ganhos para a empresa</h3>

<ul>
<li>Melhor comunicação entre devel e infra (diminuição de conflitos)</li>
<li>Soluções rodando com maior estabilidade e desempenho</li>
<li>Entregas mais rápidas</li>
<li>Menor tempo de paradas</li>
<li>Diminuição de incidentes</li>
<li>Diminuição de custos</li>
<li>Diminuição de riscos</li>
<li>Aumento do valor do negócio</li>
</ul>


<h2>8. Amarrando as pontas</h2>

<p>Vamos partir para perguntas e respostas no melhor estilo FAQ.</p>

<h3>8.1 Indo direto ao ponto (e respondendo as perguntas do início)</h3>

<p>Respondendo sobre o termo DevOps:</p>

<ol>
<li><p>DevOps está diretamente relacionado a um melhor feedback entre as áreas de TI.</p></li>
<li><p>DevOps é um movimento, é um conceito, é uma cultura e uma filosofia, e não existe uma explicação fácil.</p></li>
<li><p>DevOps possibilita diminuição dos riscos de mudanças através do uso de um ferramental adequado e adoção de uma cultura específica.</p></li>
<li><p>DevOps busca entregar sistemas melhores, com menor custo, fazendo isto de forma mais rápida e com menor risco.</p></li>
<li><p>DevOps envolve a área de Infra e Devel primáriamente.</p></li>
<li><p>DevOps é pura metodologia ágil tando na Infra quanto no Devel.</p></li>
<li><p>DevOps só funciona se as equipes de infra e devel estiverem dispostas a ceder, mudar sua cultura e método de trabalho.</p></li>
<li><p>DevOPs não é um cargo, tão pouco um setor ou departamento, é uma cultura.</p></li>
<li><p>DevOps não está restrito ao ambiente das startups, é possível utilizar essa cultura no meio corporativo.</p></li>
<li><p>DevOps não é algo novo, as boas práticas estão ai desde de sempre, logo esse &#8216;juntado&#8217; de práticas não é novidade para muita gente, mas para alguns serve como uma boa referência para aplicar mudanças necessárias.</p></li>
</ol>


<p>Respondendo sobre o especialista em DevOps:</p>

<ol>
<li><p>O especialista em DevOps de hoje é normalmente alguém que conhece muito de infra e tem uma base sólida de devel.</p></li>
<li><p>O especialista em DevOps também pode ser alguém que veio do devel e que tem uma base sólida de infra (esse geralmente é mais completo).</p></li>
</ol>


<h3>8.2 Quero ser um DevOps e não sei por onde começar</h3>

<p>Não há um tutorial para isto, minha recomendação é que você estude desenvolvimento ágil e procure entender o processo
de desenvolvimento do local onde você trabalha, estude ferramentas para desenvolvimento contínuo, estude ferramentas
de gerência de configuração, orquestração e provisionamento, fazendo isto você poderá dar os primeiros passos como
entusiasta da cultura DevOps e estará apto a atuar em seu ambiente, você poderá agir como uma
ponte entre as áreas de devel e infra, e principalmente, poderá modernizar os processos e o ambiente de infra.</p>

<h3>8.3 Eu trabalho com infra ágil, sou um DevOps?</h3>

<p>Não existe uma entidade certificadora, uma prova ou alguém que possa lhe conceder este título,
não existe um manual de conduta para dizer se você é um DevOps ou não, mas em 2013 é bastante comum encontrar
profissionais que estão estudando infraestruta ágil e se denominando DevOps.</p>

<p>Se você está buscando melhorar seu ambiente, entregar mais rápido, entregar algo com mais qualidade,
algo que minimize custos, algo que diminua riscos, algo que envolva automatização pesada, se você trabalha infraestrutura como código, se
você está atuando como um agente de mudanças em sua equipe, penso que DevOps é um termo adequado para descrever o seu trabalho,
mesmo que não esteja diretamente envolvido com uma equipe de Devel.</p>

<h3>8.4 Não existe receita mágica ou caminho rápido</h3>

<p>Como eu já mencionei não existe uma metodologia clara, DevOps ainda é um movimento em constante construção e definição, eu citei uma série de melhorias que fazem parte da cultura DevOps, cabe a cada empresa ou a cada gestor estudar e descobrir a melhor forma de combinar essas pequenas receitas técnicas e aplicar em seu ambiente.</p>

<p>Espero que este artigo tenha te ajudado a entender melhor a cultura DevOPs.</p>

<h2>9. Referências</h2>

<p>Sites</p>

<ul>
<li>http://www.kartar.net/2010/02/what-devops-means-to-me/</li>
<li>http://itrevolution.com/the-convergence-of-devops/</li>
<li>http://devopsdays.org/events/</li>
<li>http://devopsweekly.com</li>
</ul>


<p>Slides</p>

<ul>
<li>http://www.slideshare.net/jallspaw/10-deploys-per-day-dev-and-ops-cooperation-at-flickr</li>
<li>http://www.slideshare.net/KrisBuytaert/devops-the-future-is-here-its-just-not-evenly-distributed-yet</li>
<li>http://www.slideshare.net/jedi4ever/devops-is-a-verb-its-all-about-feedback-13174519</li>
<li>http://www.slideshare.net/jedi4ever/devops-the-war-is-over-if-you-want-it</li>
<li>http://www.slideshare.net/jedi4ever/devops-tools-fools-and-other-smart-things</li>
<li>http://lanyrd.com/2012/berlindevops-july/swzgt/#link-kryx</li>
<li>http://www.slideshare.net/wickett/the-devops-way-of-delivering-results-in-the-enterprise</li>
</ul>


<p>Fonte das imagens</p>

<p>[1] Dev OPs: https://devcentral.f5.com/blogs/us/devops-is-not-all-about-automation<br
[2] Rugby: http://imgfave.com  <br>
[3] Ops Burn: http://devops.com<br>
[4] Combusível: www.huffingtonpost.com<br>
[5] DevOps Diagram: http://www.skybotsoftware.com/skynews/2012/07/24/why-devops-more-trend<br></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[HAPROXY balanceando JBOSS]]></title>
    <link href="http://gutocarvalho.net/octopress/2013/03/15/haproxy-balanceando-jboss/"/>
    <updated>2013-03-15T15:20:00-03:00</updated>
    <id>http://gutocarvalho.net/octopress/2013/03/15/haproxy-balanceando-jboss</id>
    <content type="html"><![CDATA[<p>Este post estava encostado há algum tempo, finalmente consegui tempo para publicá-lo.</p>

<p>Há alguns meses um leitor me pediu ajuda com o HAPROXY, ele disse que havia visto em minha wiki alguns exemplos de uso, mas queria algo mais focado no JBOSS, este leitor tinha uma necessidade específica e resolvi ajudá-lo, mesmo não sendo especialista e não conhecendo a fundo a ferramenta.</p>

<p>Abaixo segue o roteiro completo de nossos estudos e descobertas.</p>

<h2>1. Sobre o HAPROXY</h2>

<p>O <a href="http://haproxy.1wt.eu/">HAProxy</a> é uma solução - opensource - que oferece recursos de High Availbility, Load Balance e PROXY para aplicações baseadas em TCP e HTTP. Ele foi particularmente desenhado e pensado para web sites com grande carga que necessitam de persistência ou processamentos específicos na camada de aplicação (layer7). Ele suporta milhares de conexões em hardwares muito modestos. É uma ferramenta fácil de instalar, configurar, operar e principalmente fácil de integrar aos ambientes e arquiteturas existentes.</p>

<p>Existem casos documentados de ambientes HAPROXY atendendo demandas que geravam de 3 a 6 Gibabits de tráfego - por segundo. Existem <a href="http://haproxy.1wt.eu/10g.html">testes</a> de laboratório feitos pelo criador da ferramenta demonstram que ele chegou a atender cerca de 106 mil requisições HTTP por segundo, e encaminhar (HTTP FORWARD) cerca de 40 mil requisições por segundo para backends internos.</p>

<p>Mas quem usa o HAPROXY?</p>

<p>AMAZON, TWITTER, REDDIT, FARMVILLE, GITHUB, TUMBLR, DISQUS, FEDORA, REDHAT CLOUD, STACKOVERFLOW.</p>

<p>* Dados retirados de <a href="http://haproxy.1wt.eu/they-use-it.html">http://haproxy.1wt.eu/they-use-it.html</a></p>

<h2>2. HAPROXY</h2>

<h3>2.1 Instalando</h3>

<p>A instalação é bastante simples, vou mostrar como instalar no Debian e CentOS.</p>

<p>No Debian</p>

<pre><code>aptitude install haproxy
</code></pre>

<p>No CentOS</p>

<pre><code>yum install haproxy
</code></pre>

<p>Se preferir compile - recomendado - a última versão disponível, basta fazer o download dos sources no site do <a href="http://haproxy.1wt.eu/download/1.4/src/">haproxy</a>.</p>

<h3>2.2 Cenário</h3>

<p>O leitor queria balancear uma aplicação de ensino a distância, tipo moodle, porém a ferramenta foi escrita em Java. Em seu ambiente ele tinha dois servidores bem robustos rodando JBOSS, e um servidor mais modesto em standby, estes por sua vez, sustentavam a aplicação de EAD.</p>

<h3>2.3 Configuração</h3>

<p>O arquivo de configuração tem o nome de haproxy.cfg, ele normalmente está no diretório /etc/haproxy.</p>

<p>A configuração proposta foi a seguinte:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>global
</span><span class='line'>  log 127.0.0.1   local0
</span><span class='line'>  log 127.0.0.1   local1 notice info
</span><span class='line'>  maxconn 25000   # numero maximo de conexoes que ele vai atender
</span><span class='line'>  user haproxy
</span><span class='line'>  group haproxy
</span><span class='line'>  daemon
</span><span class='line'>  nbproc  2 # numero de processadores
</span><span class='line'>
</span><span class='line'>defaults
</span><span class='line'>     contimeout      5000
</span><span class='line'>     clitimeout      50000
</span><span class='line'>     srvtimeout      50000
</span><span class='line'>     retries  3
</span><span class='line'>
</span><span class='line'>listen  sistema    0.0.0.0:80
</span><span class='line'> 
</span><span class='line'>     log     global
</span><span class='line'>     mode    http
</span><span class='line'>     option httplog
</span><span class='line'>     option dontlognull
</span><span class='line'>     option redispatch
</span><span class='line'>     option forwardfor
</span><span class='line'>     option httpclose
</span><span class='line'>     option forceclose
</span><span class='line'>     option persist
</span><span class='line'>     stats enable
</span><span class='line'>     stats auth admin:proinfo
</span><span class='line'>     stats uri /haproxy_stats
</span><span class='line'>     stats realm HAProxy\ Statistics
</span><span class='line'>     cookie  SERVERID insert indirect nocache
</span><span class='line'>     balance roundrobin
</span><span class='line'>     server  app01 10.1.1.1:8080 cookie A weight 1 maxconn 5000 inter 2s rise 2 fall 3 check
</span><span class='line'>     server  app02 10.1.1.2:8080 cookie B weight 1 maxconn 5000 inter 2s rise 2 fall 3 check
</span><span class='line'>     server  app03 10.1.1.3:8080 cookie B weight 1 maxconn 5000 inter 2s rise 2 fall 3 check backup</span></code></pre></td></tr></table></div></figure>


<h4>2.3.1 section global</h4>

<p>A seção global do arquivo de configurações define algumas configurações globais, são elas:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>log              =&gt; configurações de log
</span><span class='line'>maxconn          =&gt; número máximo global de conexões que ele vai atender
</span><span class='line'>user             =&gt; usuário que vai rodar o serviço
</span><span class='line'>group            =&gt; grupo
</span><span class='line'>daemon           =&gt; forma de funcionamento, no caso standalone
</span><span class='line'>nbproc           =&gt; número de processadores</span></code></pre></td></tr></table></div></figure>


<h4>2.3.2 section defaults</h4>

<p>A seção defaults define algumas configurações padrão para os listeners e backends.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>contimeout       =&gt; tempo máximo que o servidor aguarda para um conexão ser estabelecida
</span><span class='line'>clitimeout       =&gt; tempo máximo de inatividade no lado do cliente
</span><span class='line'>srvtimeout       =&gt; tempo máximo de inatividade no lado do servidor
</span><span class='line'>retries          =&gt; qts vezes o clt ainda deve tentar se conectar após uma falha</span></code></pre></td></tr></table></div></figure>


<h4>2.3.3 section listen</h4>

<p>Está seção define as portas que o HAPROXY vai abrir e escutar, além disto é aqui que fazemos todas as configurações de balanceamento. Abaixo a explicação de cada parâmetro:</p>

<pre><code> log                                      =&gt; confs de log, no caso confs do global

 mode    http                             =&gt; modo de funcionamento (http ou tcp )

 option httplog                           =&gt; habilita log http
 option dontlognull                       =&gt; não loga conexões de checagem, ajuda a evitar log poluído
 option redispatch                        =&gt; limpar o cookie caso o backend caia
 option forwardfor                        =&gt; para empurrar o ip do cliente para o backend
 option httpclose                         =&gt; ajuda a fechar conexões que já deveriam ter sido encerradas
 option forceclose                        =&gt; ajuda a fechar conexões que já deveriam ter sido encerradas
 option persist                           =&gt; habilitando persistentica

 stats enable                             =&gt; habilita estatísticas
 stats auth admin:password                =&gt; usuário/senha para acessar stats
 stats uri /haproxy_stats                 =&gt; url das estatísticas
 stats realm HAProxy\ Statistics          =&gt; realm de autenticação

 cookie  SERVERID insert indirect nocache =&gt; injeta cookie na conexao

 balance roundrobin                       =&gt; tipo de balanceamento
</code></pre>

<h5>2.3.3.1 parâmetro cookie</h5>

<pre><code>SERVERID   =&gt; nome do cookie que será inserido, caso necessário
indirect   =&gt; não insere cookie se o cliente já tiver um cookie válido
insert     =&gt; insere um cookie para controle de persistência de sessão caso seja necessário
nocache    =&gt; se cookie for inserido (insert) orienta a não fazer cache
</code></pre>

<h5>2.3.3.2 parâmetro balancer e server</h5>

<p>Veja abaixo que a configuração de balanceamento possui três backends com diversos parâmetros definidos para eles.</p>

<pre><code> server  sistema_01 10.1.1.1:8080 cookie A weight 1 maxconn 5000 inter 2s rise 2 fall 3 check
 server  sistema_02 10.1.1.2:8080 cookie B weight 1 maxconn 5000 inter 2s rise 2 fall 3 check
 server  sistema_03 10.1.1.3:8080 cookie C weight 1 maxconn 5000 inter 2s rise 2 fall 3 check backup
</code></pre>

<p>Vamos entender agora para que serve cada parâmetro:</p>

<pre><code>check     =&gt; verifica se a porta está aberta no servidor do pool
cookie    =&gt; nome do cookie que será injetado no lado do cliente
backup    =&gt; essa maquina só vai entrar se uma instância do pool estiver fora
inter     =&gt; significa que ele fará checagens no backend a cada 2 segundos
rise      =&gt; significa que a maquina só volta para o pool se tiver 2 checagens positivas
fall      =&gt; significa que a maquina só sairá do pool se tiver pelo menos 3 checagens negativas
maxconn   =&gt; número máximo de conexões que a instância deve receber
weight    =&gt; peso que a instância terá no pool, quando maior mais conexões vão para ele
</code></pre>

<h4>2.4 Estatísticas</h4>

<p>Para acessar as estatísticas habilitadas na configuração proposta, basta apontar seu navegador para o endereço abaixo:</p>

<pre><code>http://ip-do-servidor-haproxy/haproxy_stats
</code></pre>

<p>Através desta ferramenta de estatística, você terá dados completos sobre o balanceamento.</p>

<p>* Vai pedir o usuário e senha definidos na configuração.</p>

<h4>2.5 Entendendo a configuração</h4>

<p>Abaixo explico em 6 passos rápidos a configuração criada.</p>

<ol>
<li>A configuração <strong>option persist</strong> força o acesso a um servidor do balanceamento que esteja demorando a responder, em caso de servidores que atendem muitas requisições isso é importante, as vezes ele não está fora só está lento.</li>
<li>Estamos injetando um cookie (<strong>cookie  SERVERID insert indirect nocache</strong>) com nome SERVERID para organizar o balanceamento e manter a persistência de sessão. Quando um cliente chega, o haproxy injeta um cookie SERVERID=A/B/C para ele, assim quando ele voltar a conectar, vai trazer a informação do cookie (SERVERID=A) e a partir disto cair no mesmo servidor que ele iniciou a conexão, assim ele mantém a persistência na sessão.</li>
<li>É muito bom ter a persistência configurada, porém se uma máquina do balanceamento sair do ar, alguns clientes não irão conseguir fazer flush no cookie, com isso eles ficarão perdidos, com o <strong>option REDISPATCH</strong> isso é resolvido, o cookie é resetado caso o backend tenha sido removido do balanceamento e a partir daí a requisição vai para o próximo servidor disponível.</li>
<li>O <strong>option forwardfor</strong> é utilizado para empurrar o IP do cliente para o backend ao invés de empurrar o IP do HAPROXY, isso é bom quando queremos gerar estatísticas usando ferramentas como AWSTATS, estas ferramentas normalmente fazem leitura dos logs dos backends.</li>
<li>O <strong>option httpclose</strong> e <strong>option forceclose</strong> são utilizados para fechar conexões. Algumas vezes alguns servidores ao receberem o <strong>httpclose</strong>, mesmo assim ainda mantém a conexão aberta com o cliente, deixando ela cair por timeout, isso pode ocasionar centenas e as vezes milhares de conexões desnecessárias esperando timeout, esses dois parâmetros resolvem isto, fechando a conexão assim que o servidor terminar de responder.</li>
<li>Configuramos 3 backends, 2 ativos e um em standby (backup), esse último só entrará no balanceamento caso um dos backends principais seja removido por alguma razão, essa máquina é mais modesta, por isto está em modo backup.</li>
</ol>


<h2>3. Amarrando as pontas</h2>

<p>Segundo o leitor, até hoje o balanceamento está funcionando redondinho, e ele por sinal está bastante feliz.</p>

<p>Tive que ler bastante para ajudá-lo na configuração, isso me ajudou a desenferrujar no HAPROXY, e olha que havia um bom tempo em que eu não usava ele para algo, finalmente surgiu uma boa oportunidade.</p>

<p>O HAPROXY ainda tem centenas de recursos para conhecer, alguns muito interessantes para PROXY e LOAD BALANCER, ele tem suporte a ACLs para redirecionamentos especiais, podemos construir regras fantásticas usando ACLs.</p>

<p>Outra questão sensacional é o balanceamento TCP, posso virtualmente criar um balanceamento na camada 4 utilizando apenas esta ferramenta, com isso posso balancear IMAP, POP, SMTP e qualquer outra aplicação que atenda clientes utilizando uma porta TCP.</p>

<p>Logo podemos dizer que com o HAPROXY você pode construir seu próprio SWITCH de conteúdo.</p>

<p>Se quiser criar um ambiente com HA para seu HAPROXY recomendo o uso do KEEPALIVED. Acesse o site do <a href="http://andyleonard.com/2011/02/01/haproxy-and-keepalived-example-configuration/">Andy Leonard</a> para ler um bom tutorial sobre esse assunto.</p>

<p>Eu já vi casos de uso do NGINX para fazer proxy reverso e o HAPROXY para balanceamento, afinal ele é especializado nisto.</p>

<p>Já vi cenários com NGINX + HAPROXY + VARNISH (PROXY => BALANCEAMENTO => CACHE).</p>

<p>A grande vantagem do HAPROXY na minha opinião é que ele é uma ferramenta especializada em balanceamento, diferente de outras ferramentas que também fazem balanceamento, mas não são especializadas nisto. O HAPROXY é incrivelmente performatico e usa poucos recursos do servidor (MEM/PROC) para fazer seu trabalho.</p>

<p>Eu particularmente gosto muito desta ferramenta e das possibilidades que ela me oferece, recomendo de olhos fechados.</p>

<p>* Caso alguém que conheça melhor a ferramenta tenha visto algo errado, por favor nos avise e ajude melhorar este estudo, como eu já disse, sou um admirador da ferramenta mas não um grande conhecedor :)</p>

<h2>4. Referências</h2>

<ul>
<li>http://haproxy.1wt.eu/</li>
<li>https://code.google.com/p/haproxy-docs</li>
<li>http://gutocarvalho.net/dokuwiki/doku.php/haproxy_exemplos</li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Mcollective Shell Agent]]></title>
    <link href="http://gutocarvalho.net/octopress/2013/03/09/mcollective-shell-agent/"/>
    <updated>2013-03-09T18:51:00-03:00</updated>
    <id>http://gutocarvalho.net/octopress/2013/03/09/mcollective-shell-agent</id>
    <content type="html"><![CDATA[<h2>1. Sobre o Marionette Collective</h2>

<p>O Mcollective é um framework que te permite trabalhar com orquestração de servidores ou execução paralela de tarefas em seus nodes.</p>

<p>Em essência, orquestração significa invocar ações em paralelo em todo o seu parque de servidores de uma forma direta, eficiente e além disto em tempo real.</p>

<h2>2. Agente Shell</h2>

<p>No post anterior, apresentei alguns agentes do Mcollective que executam ações pontuais, no entanto, não é possível através destes agentes rodar comandos arbitários em nossos nodes.</p>

<p>O próprio criador do Mcollective (<a href="http://www.devco.net/">R.I.Pienaar</a>) não recomenda que sejam escritos plugins para execução de comandos arbitrários, e ele tem razão, é perigoso e você não conseguirá prever a saída do comando no outro lado.</p>

<p>Porém, eventualmente precisamos fazer isto, e neste caso existem alguns plugins disponíveis no GITHUB, aqui neste post vou mostrar como instalar um plugin que contém um agente para execução de comandos em ambiente shell.</p>

<h3>2.1 Instalando o agente</h3>

<p>Partindo do pressuposto de que você já tem o Mcollective rodando, vamos apenas instalar o agente shell e ver como ele funciona. Aqui neste post vou usar o agente escrito por <a href="https://github.com/phobos182/mcollective-plugins/">Jeremy Caroll</a>.</p>

<p>Faça download do arquivo shell.rb</p>

<pre><code>wget https://raw.github.com/phobos182/mcollective-plugins/master/agent/shell/shell.rb
</code></pre>

<p>Faça download do arquivo shell.ddl</p>

<pre><code>wget https://raw.github.com/phobos182/mcollective-plugins/master/agent/shell/shell.ddl
</code></pre>

<p>Mova os arquivos para o diretório agent do mcollective</p>

<pre><code>mv shell.rb shell.ddl /usr/share/mcollective/plugins/mcollective/agent
</code></pre>

<p>Agora faça download do arquivo de aplicação shell.rb (é outro arquivo)</p>

<pre><code>wget https://raw.github.com/phobos182/mcollective-plugins/master/agent/shell/application/shell.rb
</code></pre>

<p>Mova o arquivo para o diretório application do mcollective</p>

<pre><code>mv shell.rb /usr/share/mcollective/plugins/mcollective/application
</code></pre>

<p>Agora reinicie o agente.</p>

<pre><code>/etc/init.d/mcollective restart
</code></pre>

<p>Instale os arquivos em todos os nodes que deseja utilizar o agente shell.</p>

<h3>2.2 Utilizando o agente</h3>

<p>A utilização é bastante simples, observe a sintaxe:</p>

<pre><code>mco shell &lt;comando&gt;
</code></pre>

<p>Vamos a um exemplo</p>

<pre><code>mco shell uptime
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Do you really want to send this command unfiltered? (y/n): y
</span><span class='line'>Discovering hosts using the mc method for 2 second(s) .... 2
</span><span class='line'>
</span><span class='line'> * [ ============================================================&gt; ] 2 / 2
</span><span class='line'>
</span><span class='line'>[puppet.hacklab] exit=0:
</span><span class='line'>[debian.hacklab] exit=0:</span></code></pre></td></tr></table></div></figure>


<p>Veja que o comando foi executado em dois nodes, mas repare que apenas fomos informados disto, caso deseje ver a saída, será necessário adicionar um parâmetro.</p>

<pre><code>mco shell uptime --verbose
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Do you really want to send this command unfiltered? (y/n): y
</span><span class='line'>Discovering hosts using the mc method for 2 second(s) .... 2
</span><span class='line'>
</span><span class='line'> * [ ============================================================&gt; ] 2 / 2
</span><span class='line'>
</span><span class='line'>[puppet.hacklab] exit=0:  13:56:48 up 28 min,  2 users,  load average: 0.00, 0.00, 0.00
</span><span class='line'>[debian.hacklab] exit=0:  13:56:44 up 28 min,  2 users,  load average: 0.00, 0.00, 0.00</span></code></pre></td></tr></table></div></figure>


<h3>2.3 Exemplos de uso do agente</h3>

<h4>2.3.1 Lendo arquivo /etc/issue</h4>

<p>Vamos usar o cat para ler o conteúdo do arquivo issue</p>

<pre><code>mco shell "cat /etc/issue" --verbose
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Do you really want to send this command unfiltered? (y/n): y
</span><span class='line'>Discovering hosts using the mc method for 2 second(s) .... 2
</span><span class='line'>
</span><span class='line'> * [ ============================================================&gt; ] 2 / 2
</span><span class='line'>
</span><span class='line'>[debian.hacklab] exit=0: Debian GNU/Linux 6.0 \n \l
</span><span class='line'>
</span><span class='line'>[puppet.hacklab] exit=0: Debian GNU/Linux 6.0 \n \l</span></code></pre></td></tr></table></div></figure>


<h4>2.3.2 Rodando comando df</h4>

<p>Vamos rodar o comando df -h para ver dados de uso das partições e disco.</p>

<pre><code>mco shell "df -h" --verbose
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Do you really want to send this command unfiltered? (y/n): y
</span><span class='line'>Discovering hosts using the mc method for 2 second(s) .... 2
</span><span class='line'>
</span><span class='line'> * [ ============================================================&gt; ] 2 / 2
</span><span class='line'>
</span><span class='line'>[puppet.hacklab] exit=0: Filesystem            Size  Used Avail Use% Mounted on
</span><span class='line'>/dev/sda1             3.8G  2.1G  1.6G  57% /
</span><span class='line'>tmpfs                 188M     0  188M   0% /lib/init/rw
</span><span class='line'>udev                  184M  124K  184M   1% /dev
</span><span class='line'>tmpfs                 188M     0  188M   0% /dev/shm
</span><span class='line'>
</span><span class='line'>[debian.hacklab] exit=0: Filesystem            Size  Used Avail Use% Mounted on
</span><span class='line'>/dev/sda1             3.8G 1002M  2.6G  28% /
</span><span class='line'>tmpfs                 125M     0  125M   0% /lib/init/rw
</span><span class='line'>udev                  121M  124K  120M   1% /dev
</span><span class='line'>tmpfs                 125M     0  125M   0% /dev/shm</span></code></pre></td></tr></table></div></figure>


<h2>3. Amarrando as pontas</h2>

<p>O criador do Mcollective (<a href="http://www.devco.net/">R.I.Pienaar</a>) recomenda que você escreva seus agentes usando simpleRPC, agentes que executem tarefas pontais, agentes no quais você tem controle, agentes nos quais você pode confiar, agentes nos quais você conhece o risco de utilizar em sua infra, e tenho que dizer que eu concordo com isto, portanto, use esse agente ssh por sua conta e risco ;)</p>

<p>Eu assumo o risco pois o que preciso fazer com ele é bem simples, mas cada caso é um caso.</p>

<h3>3.1 Exemplificando os riscos</h3>

<p>Só para você ter uma ideia de tragédias possíveis, imagine o risco potencial de alguém rodar - sem querer - algo como abaixo:</p>

<pre><code>mco shell "rm -rf /"
</code></pre>

<p>Isto simplesmente apagaria todo o seu parque, é muito poder para pouca segurança. Espero que este exemplo tenha sido suficientemente claro :)</p>

<h3>3.1 Facilitando a instalação</h3>

<p>Eu escrevi dois módulos para Puppet que facilitam a instalação do Mcollective e dos agentes, segue abaixo os links.</p>

<p><a href="https://github.com/gutocarvalho/puppet-mcollective-debian">https://github.com/gutocarvalho/puppet-mcollective-debian</a></p>

<p><a href="https://github.com/gutocarvalho/puppet-rabbitmq-debian">https://github.com/gutocarvalho/puppet-rabbitmq-debian</a></p>

<p>O agente SSH já está incluso no módulo.</p>

<h2>4. Referências</h2>

<ul>
<li>http://www.devco.net</li>
<li>https://github.com/phobos182/mcollective-plugins</li>
<li>https://github.com/puppetlabs/mcollective-plugins</li>
<li>https://puppetlabs.com/mcollective/introduction</li>
</ul>


<p>[s]<br>
Guto</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Instalando Mcollective em Debian Squeeze com Ambiente Puppet]]></title>
    <link href="http://gutocarvalho.net/octopress/2013/02/07/instalando-mcollective-em-debian-squeeze-com-ambiente-puppet/"/>
    <updated>2013-02-07T11:06:00-02:00</updated>
    <id>http://gutocarvalho.net/octopress/2013/02/07/instalando-mcollective-em-debian-squeeze-com-ambiente-puppet</id>
    <content type="html"><![CDATA[<h2>1. Sobre o Marionette Collective</h2>

<p>O Mcollective é um framework que te permite trabalhar com orquestração de servidores ou execução paralela de tarefas em seus nodes.</p>

<p>Em essência, orquestração significa invocar ações em paralelo em todo o seu parque de servidores de uma forma direta, eficiente e além disto em tempo real.</p>

<h2>2. Entendendo a necessidade</h2>

<p>Vamos supor que por alguma razão você precise rodar algum comando em todos os seus servidores, seja para atualizar um pacote, seja para desligar um serviço, seja para remover um usuário ou aplicar uma regra e firewall, enfim, por qualquer que seja a razão.</p>

<p>Sabemos que o puppet permite esse tipo de abordagem, porém não te permite fazer isto em tempo real, com o puppet você precisar criar um manifest, declarar a classe de seu manifest para seus nodes e esperar que os agentes consultem o servidor, recebam o catálogo e iniciem a aplicação das mudanças declaradas no manifest. Isto pode levar minutos ou horas dependendo do tamanho do seu parque e de como os agentes estão configurados.</p>

<p>Se sua necessidade é executar algo em tempo real, de forma paralela, o mcollective é a ferramenta certa para fazer isto em seu parque de servidores.</p>

<h2>3. Objetivos deste artigo</h2>

<p>Aqui pretendo abordar a instalação do Mcollective em ambiente Debian.</p>

<h2>4. Ambiente</h2>

<p>2 VMs&#8217; Virtualbox - Debian Squeeze - 64 Bits</p>

<pre><code>vm1: 192.168.56.50 puppet.hacklab (puppet master)
vm2: 192.168.56.51 debian.hacklab (puppet agent )
</code></pre>

<h2>5 Pre-Reqs</h2>

<h3>5.1 Repositório debian</h3>

<p>Nas duas VM&#8217;s adicione os repositórios abaixo ao seu sources.list</p>

<p>Edite o arquivo</p>

<pre><code>vim /etc/apt/sources.list
</code></pre>

<p>Adicione as linhas ao final do arquivo</p>

<pre><code>deb http://apt.puppetlabs.com squeeze main
deb http://www.rabbitmq.com/debian/ testing main
</code></pre>

<p>Salve as alterações</p>

<pre><code>:wq
</code></pre>

<p>Atualize os índices</p>

<pre><code>aptitude update
</code></pre>

<p>Pronto, agora você poderá instalar o mcollective usando o aptitude.</p>

<h3>5.2 Ambiente Puppet</h3>

<p>Nas duas VM&#8217;s é necessário que já exista um ambiente Puppet instalado e rodando em modo cliente/servidor, não vou entrar em detalhes pois já cobri esse processo de forma completa em minha <a href="http://gutocarvalho.net/dokuwiki/doku.php/puppetmaster">wiki</a>.</p>

<pre><code>vm1: puppet.hacklab (puppet master)
vm2: debian.hacklab (puppet agent )
</code></pre>

<p>Ressalto que é importante ter o puppet funcionando nas VM&#8217;s para podermos utilizar o agente puppet, package e service do Mcollective.</p>

<h2>6. Configurando VM1 (puppet master)</h2>

<h3>6.1 Instalando RabbitMQ</h3>

<h4>6.1.1 Sobre o RabbitMQ</h4>

<p>O Mcollective (MCO) depende de algum sistema de mensageria, é possível utilizar tanto o ApacheMQ quanto o RabbitMQ, ambos tem suporte ao protocolo STOMP, necessário para o funcionamento do MCO.</p>

<p>Neste estudo vou utilizar o RabbitMQ, mas é possível - e até recomendado - utilizar o ActiveMQ.</p>

<h4>6.1.2 Instalando o ActiveMQ</h4>

<p>Instale o rabbitmq 3.0.2 (vigente neste momento)</p>

<pre><code>aptitude install rabbitmq-server
</code></pre>

<p>Edite o arquivo /etc/rabbitmq/rabbitmq.config e coloque apenas o conteúdo abaixo, limpe o resto</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>[
</span><span class='line'>  {rabbitmq_stomp, [{tcp_listeners, [{"0.0.0.0", 6163},
</span><span class='line'>                                     {"::1",       6163}]}]}
</span><span class='line'>].</span></code></pre></td></tr></table></div></figure>


<p></p>

<p>Edite o arquivo /etc/default/rabbitmq-server e descomente a linha abaixo</p>

<pre><code>ulimit -n 1024
</code></pre>

<p>reinicie o serviço</p>

<pre><code>/etc/init.d/rabbitmq-server restart
</code></pre>

<p>Verfique o status do serviço</p>

<pre><code>/etc/init.d/rabbitmq-server status
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Status of node rabbit@puppet ...
</span><span class='line'>[{pid,7390},
</span><span class='line'> {running_applications,[{rabbit,"RabbitMQ","3.0.2"},
</span><span class='line'>                        {mnesia,"MNESIA  CXC 138 12","4.4.14"},
</span><span class='line'>                        {os_mon,"CPO  CXC 138 46","2.2.5"},
</span><span class='line'>                        {sasl,"SASL  CXC 138 11","2.1.9.2"},
</span><span class='line'>                        {stdlib,"ERTS  CXC 138 10","1.17"},
</span><span class='line'>                        {kernel,"ERTS  CXC 138 10","2.14"}]},
</span><span class='line'> {os,{unix,linux}},
</span><span class='line'> {erlang_version,"Erlang R14A (erts-5.8) [source] [rq:1] [async-threads:30] [kernel-poll:true]\n"},
</span><span class='line'> {memory,[{total,12888616},
</span><span class='line'>          {connection_procs,1344},
</span><span class='line'>          {queue_procs,2688},
</span><span class='line'>          {plugins,0},
</span><span class='line'>          {other_proc,4592340},
</span><span class='line'>          {mnesia,28704},
</span><span class='line'>          {mgmt_db,0},
</span><span class='line'>          {msg_index,7020},
</span><span class='line'>          {other_ets,363324},
</span><span class='line'>          {binary,3680},
</span><span class='line'>          {code,6394787},
</span><span class='line'>          {atom,796661},
</span><span class='line'>          {other_system,698068}]},
</span><span class='line'> {vm_memory_high_watermark,0.4},
</span><span class='line'> {vm_memory_limit,157546905},
</span><span class='line'> {disk_free_limit,1000000000},
</span><span class='line'> {disk_free,2638680064},
</span><span class='line'> {file_descriptors,[{total_limit,924},
</span><span class='line'>                    {total_used,3},
</span><span class='line'>                    {sockets_limit,829},
</span><span class='line'>                    {sockets_used,1}]},
</span><span class='line'> {processes,[{limit,1048576},{used,121}]},
</span><span class='line'> {run_queue,0},
</span><span class='line'> {uptime,5}]
</span><span class='line'>...done.</span></code></pre></td></tr></table></div></figure>


<p>Crie um usuário para o mcollective</p>

<pre><code>rabbitmqctl add_user mcollective senhapuppet
</code></pre>

<p>Especifique as permissões para o usuário do mcollective</p>

<pre><code>rabbitmqctl set_permissions -p / mcollective "^amq.gen-.*" ".*" ".*"
</code></pre>

<p>Remova o usuário guest</p>

<pre><code>rabbitmqctl delete_user guest
</code></pre>

<p>Habilite os plugins stomp e amqp</p>

<pre><code>rabbitmq-plugins enable rabbitmq_stomp
rabbitmq-plugins enable amqp_client
</code></pre>

<h3>6.2 Instalando MCollective</h3>

<p>Instale a biblioteca stomp para ruby</p>

<pre><code>aptitude install libstomp-ruby
</code></pre>

<p>Instale os pacotes mcollective da puppetlabs</p>

<pre><code>aptitude install mcollective mcollective-client
</code></pre>

<p>Configure o arquivo /etc/mcollective/server.cfg conforme abaixo</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>topicprefix = /topic/
</span><span class='line'>main_collective = mcollective
</span><span class='line'>collectives = mcollective
</span><span class='line'>libdir = /usr/share/mcollective/plugins
</span><span class='line'>logfile = /var/log/mcollective.log
</span><span class='line'>loglevel = info
</span><span class='line'>daemonize = 1
</span><span class='line'>
</span><span class='line'># Plugins
</span><span class='line'>securityprovider = psk
</span><span class='line'>plugin.psk = hacklab
</span><span class='line'>
</span><span class='line'>connector = stomp
</span><span class='line'>plugin.stomp.host = 192.168.56.50
</span><span class='line'>plugin.stomp.port = 6163
</span><span class='line'>plugin.stomp.user = mcollective
</span><span class='line'>plugin.stomp.password = senhapuppet
</span><span class='line'>
</span><span class='line'># Facts
</span><span class='line'>factsource = yaml
</span><span class='line'>plugin.yaml = /etc/mcollective/facts.yaml
</span></code></pre></td></tr></table></div></figure>


<p>Configure o arquivo /etc/mcollective/client.cfg conforme abaixo</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>topicprefix = /topic/
</span><span class='line'>main_collective = mcollective
</span><span class='line'>collectives = mcollective
</span><span class='line'>libdir = /usr/share/mcollective/plugins
</span><span class='line'>logger_type = console
</span><span class='line'>loglevel = warn
</span><span class='line'>
</span><span class='line'># Plugins
</span><span class='line'>securityprovider = psk
</span><span class='line'>plugin.psk = hacklab
</span><span class='line'>
</span><span class='line'>connector = stomp
</span><span class='line'>plugin.stomp.host = 192.168.56.50
</span><span class='line'>plugin.stomp.port = 6163
</span><span class='line'>plugin.stomp.user = mcollective
</span><span class='line'>plugin.stomp.password = senhapuppet
</span><span class='line'>
</span><span class='line'># Facts
</span><span class='line'>factsource = yaml
</span><span class='line'>plugin.yaml = /etc/mcollective/facts.yaml</span></code></pre></td></tr></table></div></figure>


<p>Reinicie o mcollective</p>

<pre><code>/etc/init.d/mcollective restart
</code></pre>

<p>Faça o teste de ping em nodes ativos usando o mco</p>

<pre><code>mco ping
</code></pre>

<p>Acompanhe a saída</p>

<pre><code>puppet.hacklab                           time=89.34 ms
---- ping statistics ----
1 replies max: 89.34 min: 89.34 avg: 89.34
</code></pre>

<p>Faça o teste de find em nodes ativos usando o mco</p>

<pre><code>mco find
</code></pre>

<p>Acompanhe a saída</p>

<pre><code>puppet.hacklab
</code></pre>

<p>Podemos ver que o MCO está funcionando corretamente, por hora detectando apenas um node.</p>

<h2>7. Configurando VM2 (puppet agent)</h2>

<p>Para instalar o Mcollective na VM2, siga as referências da seção 1.2 e tenha os repositórios devidamente configurados.</p>

<p>Após a instalação e a configuração do mcollective, faça o teste de ping em nodes ativos com mco</p>

<pre><code>mco ping
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>debian.hacklab                           time=188.49 ms
</span><span class='line'>puppet.hacklab                           time=191.91 ms
</span><span class='line'>---- ping statistics ----
</span><span class='line'>2 replies max: 191.91 min: 188.49 avg: 190.20 </span></code></pre></td></tr></table></div></figure>


<p>Faça uma busca por nodes ativos com o mco</p>

<pre><code>mco find
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>puppet.hacklab
</span><span class='line'>debian.hacklab</span></code></pre></td></tr></table></div></figure>


<p>Solicite o inventário de uma máquina</p>

<pre><code>mco inventory debian.hacklab
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Inventory for debian.hacklab:
</span><span class='line'>
</span><span class='line'>   Server Statistics:
</span><span class='line'>                      Version: 2.2.2
</span><span class='line'>                   Start Time: Wed Feb 06 14:39:55 -0200 2013
</span><span class='line'>                  Config File: /etc/mcollective/server.cfg
</span><span class='line'>                  Collectives: mcollective
</span><span class='line'>              Main Collective: mcollective
</span><span class='line'>                   Process ID: 1744
</span><span class='line'>               Total Messages: 19
</span><span class='line'>      Messages Passed Filters: 18
</span><span class='line'>            Messages Filtered: 1
</span><span class='line'>             Expired Messages: 0
</span><span class='line'>                 Replies Sent: 17
</span><span class='line'>         Total Processor Time: 0.52 seconds
</span><span class='line'>                  System Time: 0.27 seconds
</span><span class='line'>
</span><span class='line'>   Agents:
</span><span class='line'>      discovery       puppet          rpcutil        
</span><span class='line'>
</span><span class='line'>   Data Plugins:
</span><span class='line'>      agent           fstat           puppet         
</span><span class='line'>      resource                                       
</span><span class='line'>
</span><span class='line'>   Configuration Management Classes:
</span><span class='line'>      apt                            apt::params                   
</span><span class='line'>      debian.hacklab                 hostname                      
</span><span class='line'>      hosts                          linux-server                  
</span><span class='line'>      openssh-server                 puppet-agent                  
</span><span class='line'>      repos                          resolv                        
</span><span class='line'>      salt-minion                    settings                      
</span><span class='line'>      usuarios                       utils                         
</span><span class='line'>
</span><span class='line'>   Facts:
</span><span class='line'>      mcollective =&gt; 1</span></code></pre></td></tr></table></div></figure>


<p>Podemos ver que o MCO está funcionando corretamente e detectando os dois nodes.</p>

<h2>8. Agentes para Mcollective</h2>

<p>O Mcollective possui vários agentes que nos ajudam a manipular os nodes de nosso parque de forma direta, aqui vou abordar a instalação e utilização de alguns destes agentes.</p>

<p>Instale os pacotes em ambos os nodes</p>

<pre><code>aptitude install mcollective-puppet-agent mcollective-puppet-client mcollective-package-agent mcollective-package-client mcollective-service-agent mcollective-service-client
</code></pre>

<p>Reinicie o mcollective em ambos os nodes</p>

<pre><code>/etc/init.d/mcollective restart
</code></pre>

<h3>8.1 Agente puppet</h3>

<h4>8.1.1 runonce/runall</h4>

<p>Após instalar, podemos mandar executar o puppet em um node</p>

<pre><code>mco puppet runonce -I debian.hacklab
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>* [ ============================================================&gt; ] 1 / 1
</span><span class='line'>
</span><span class='line'>Finished processing 1 / 1 hosts in 112.56 ms</span></code></pre></td></tr></table></div></figure>


<p>Podemos mandar executar o agente em todos os nodes</p>

<pre><code>mco puppet runonce -v
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Discovering hosts using the mc method for 2 second(s) .... 2
</span><span class='line'>
</span><span class='line'> * [ ============================================================&gt; ] 2 / 2
</span><span class='line'>
</span><span class='line'>puppet.hacklab                          : Puppet is currently applying a catalog, cannot run now
</span><span class='line'>    {:summary=&gt;"Puppet is currently applying a catalog, cannot run now"}
</span><span class='line'>
</span><span class='line'>debian.hacklab                          : OK
</span><span class='line'>    {:summary=&gt;"Signalled the running Puppet Daemon"}
</span><span class='line'>
</span><span class='line'>---- rpc stats ----
</span><span class='line'>           Nodes: 2 / 2
</span><span class='line'>     Pass / Fail: 1 / 1
</span><span class='line'>      Start Time: Wed Feb 06 18:08:20 -0200 2013
</span><span class='line'>  Discovery Time: 2013.47ms
</span><span class='line'>      Agent Time: 43.72ms
</span><span class='line'>      Total Time: 2057.18ms</span></code></pre></td></tr></table></div></figure>


<p>Existe ainda o parâmetro <strong>runall</strong> onde você pode especificar a quantidade de ações simultâneas que serão executadas, ou seja, quantidade de agentes que serão executados de forma paralela.</p>

<pre><code>mco puppet runall 10
</code></pre>

<p>Neste caso ele vai executar o agente em todos os nodes, rodando de 10 em 10, essa pode ser um estratégia para evitar esgotamento dos recursos do servidor em parques muito grandes, desta forma, ao invés de deixar o agente ligado e consultando o servidor a cada N minutos, você pode usar o MCO para rodar o agente de forma controlada em todos os seus nodes.</p>

<h4>8.1.2 enable/disable</h4>

<p>Desabilitando puppet em um node</p>

<pre><code>mco puppet disable -I debian.hacklab
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class=''><span class='line'> * [ ============================================================&gt; ] 1 / 1
</span><span class='line'>
</span><span class='line'>Summary of Enabled:
</span><span class='line'>
</span><span class='line'>   disabled = 1
</span><span class='line'>
</span><span class='line'>Finished processing 1 / 1 hosts in 126.27 ms</span></code></pre></td></tr></table></div></figure>


<p>Habilitando puppet em um node</p>

<pre><code>mco puppet enable -I debian.hacklab
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class=''><span class='line'> * [ ============================================================&gt; ] 1 / 1
</span><span class='line'>
</span><span class='line'>Summary of Enabled:
</span><span class='line'>
</span><span class='line'>   enabled = 1
</span><span class='line'>
</span><span class='line'>Finished processing 1 / 1 hosts in 91.71 ms    </span></code></pre></td></tr></table></div></figure>


<p></p>

<p>Desabilitando puppet em todos os nodes</p>

<pre><code>mco rpc puppet disable message="doing some hand hacking"
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Discovering hosts using the mc method for 2 second(s) .... 2
</span><span class='line'>
</span><span class='line'> * [ ============================================================&gt; ] 2 / 2
</span><span class='line'>
</span><span class='line'>Summary of Enabled:
</span><span class='line'>
</span><span class='line'>   disabled = 2
</span><span class='line'>
</span><span class='line'>Finished processing 2 / 2 hosts in 201.09 ms</span></code></pre></td></tr></table></div></figure>


<p>Habilitando puppet em todos os nos nodes</p>

<pre><code>mco rpc puppet enable
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Discovering hosts using the mc method for 2 second(s) .... 2
</span><span class='line'>
</span><span class='line'> * [ ============================================================&gt; ] 2 / 2
</span><span class='line'>
</span><span class='line'>Summary of Enabled:
</span><span class='line'>
</span><span class='line'>   enabled = 2
</span><span class='line'>
</span><span class='line'>Finished processing 2 / 2 hosts in 45.02 ms</span></code></pre></td></tr></table></div></figure>


<h4>8.1.3 summary</h4>

<p>Solicitando o relatório last run</p>

<pre><code>mco puppet summary
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Summary statistics for 2 nodes:
</span><span class='line'>
</span><span class='line'>                  Total resources: ▇▁▁▇▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁  min: 62.0   max: 66.0  
</span><span class='line'>            Out Of Sync resources: ▇▇▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁  min: 0.0    max: 2.0   
</span><span class='line'>                 Failed resources: ▇▇▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁  min: 0.0    max: 2.0   
</span><span class='line'>                Changed resources: ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁  min: 0.0    max: 0.0   
</span><span class='line'>  Config Retrieval time (seconds): ▇▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁  min: 0.7    max: 1.5   
</span><span class='line'>         Total run-time (seconds): ▇▁▁▁▁▇▁▁▁▁▁▁▁▁▁▁▁▁▁▁  min: 4.4    max: 12.5  
</span><span class='line'>    Time since last run (seconds): ▇▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▇  min: 791.0  max: 1.5k  </span></code></pre></td></tr></table></div></figure>


<h4>8.1.4 count</h4>

<p>Solicitando contagem dos nodes habilitados, desabiliados e em execução</p>

<pre><code>mco puppet count
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Total Puppet nodes: 2
</span><span class='line'>
</span><span class='line'>          Nodes currently enabled: 2
</span><span class='line'>         Nodes currently disabled: 0
</span><span class='line'>
</span><span class='line'>Nodes currently doing puppet runs: 0
</span><span class='line'>          Nodes currently stopped: 2
</span><span class='line'>
</span><span class='line'>       Nodes with daemons started: 2
</span><span class='line'>    Nodes without daemons started: 0
</span><span class='line'>       Daemons started but idling: 2</span></code></pre></td></tr></table></div></figure>


<h4>8.1.5 stats</h4>

<p>Solicitando status dos agentes</p>

<pre><code>mco puppet status
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
</pre></td><td class='code'><pre><code class=''><span class='line'> * [ ============================================================&gt; ] 2 / 2
</span><span class='line'>
</span><span class='line'>   debian.hacklab: Currently idling; last completed run 30 minutes 34 seconds ago
</span><span class='line'>   puppet.hacklab: Currently applying a catalog; last completed run 6 hours 37 minutes 18 seconds ago
</span><span class='line'>
</span><span class='line'>Summary of Applying:
</span><span class='line'>
</span><span class='line'>    true = 1
</span><span class='line'>   false = 1
</span><span class='line'>
</span><span class='line'>Summary of Daemon Running:
</span><span class='line'>
</span><span class='line'>   running = 2
</span><span class='line'>
</span><span class='line'>Summary of Enabled:
</span><span class='line'>
</span><span class='line'>   enabled = 2
</span><span class='line'>
</span><span class='line'>Summary of Idling:
</span><span class='line'>
</span><span class='line'>    true = 1
</span><span class='line'>   false = 1
</span><span class='line'>
</span><span class='line'>Summary of Status:
</span><span class='line'>
</span><span class='line'>               idling = 1
</span><span class='line'>   applying a catalog = 1
</span><span class='line'>
</span><span class='line'>
</span><span class='line'>Finished processing 2 / 2 hosts in 67.61 ms</span></code></pre></td></tr></table></div></figure>


<h3>8.2 Agente service</h3>

<h4>8.2.1 agente service: stop</h4>

<p>Parando um serviço em um node específico</p>

<pre><code>mco rpc service stop service=ssh -I debian.hacklab
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class=''><span class='line'> * [ ============================================================&gt; ] 1 / 1
</span><span class='line'>
</span><span class='line'>Summary of Service Status:
</span><span class='line'>
</span><span class='line'>   stopped = 1
</span><span class='line'>
</span><span class='line'>Finished processing 1 / 1 hosts in 1166.06 ms</span></code></pre></td></tr></table></div></figure>


<p>Parando um serviço em todos os nodes</p>

<pre><code>puppet@root ~]# mco rpc service stop service=ssh
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Discovering hosts using the mc method for 2 second(s) .... 2
</span><span class='line'>
</span><span class='line'> * [ ============================================================&gt; ] 2 / 2
</span><span class='line'>
</span><span class='line'>Summary of Service Status:
</span><span class='line'>
</span><span class='line'>   stopped = 2
</span><span class='line'>
</span><span class='line'>Finished processing 2 / 2 hosts in 2546.92 ms</span></code></pre></td></tr></table></div></figure>


<h4>8.2.2 plugin service: start</h4>

<p>Iniciando o serviço em um node específico</p>

<pre><code>mco rpc service start service=ssh -I debian.hacklab
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class=''><span class='line'> * [ ============================================================&gt; ] 1 / 1
</span><span class='line'>
</span><span class='line'>Summary of Service Status:
</span><span class='line'>
</span><span class='line'>   running = 1
</span><span class='line'>
</span><span class='line'>Finished processing 1 / 1 hosts in 1204.95 ms</span></code></pre></td></tr></table></div></figure>


<p>Iniciando um serviço em todos os nodes</p>

<pre><code>mco rpc service start service=ssh
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Discovering hosts using the mc method for 2 second(s) .... 2
</span><span class='line'>
</span><span class='line'> * [ ============================================================&gt; ] 2 / 2
</span><span class='line'>
</span><span class='line'>Summary of Service Status:
</span><span class='line'>
</span><span class='line'>   running = 2
</span><span class='line'>
</span><span class='line'>Finished processing 2 / 2 hosts in 3271.52 ms</span></code></pre></td></tr></table></div></figure>


<h4>8.2.3 plugin service: restart</h4>

<p>Reiniciando um serviço em um node específico</p>

<pre><code>mco rpc service restart service=ssh -I debian.hacklab
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
</pre></td><td class='code'><pre><code class=''><span class='line'> * [ ============================================================&gt; ] 1 / 1
</span><span class='line'>
</span><span class='line'>
</span><span class='line'>Summary of Service Status:
</span><span class='line'>
</span><span class='line'>   running = 1
</span><span class='line'>
</span><span class='line'>Finished processing 1 / 1 hosts in 1015.66 ms</span></code></pre></td></tr></table></div></figure>


<p>Reiniciando um serviço em todos os nodes</p>

<pre><code>mco rpc service restart service=ssh
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Discovering hosts using the mc method for 2 second(s) .... 2
</span><span class='line'>
</span><span class='line'> * [ ============================================================&gt; ] 2 / 2
</span><span class='line'>
</span><span class='line'>Summary of Service Status:
</span><span class='line'>
</span><span class='line'>   running = 2
</span><span class='line'>
</span><span class='line'>Finished processing 2 / 2 hosts in 5466.57 ms</span></code></pre></td></tr></table></div></figure>


<h3>8.3 Agente package</h3>

<h4>8.3.1 agente package: install</h4>

<p>Instalando o pacote em um node específico</p>

<pre><code>mco rpc package install package=htop -I debian.hacklab
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class=''><span class='line'> * [ ============================================================&gt; ] 1 / 1
</span><span class='line'>
</span><span class='line'>debian.hacklab                           Unknown Request Status
</span><span class='line'>   Package is already installed
</span><span class='line'>
</span><span class='line'>Summary of Ensure:
</span><span class='line'>
</span><span class='line'>   0.8.3-1 = 1
</span><span class='line'>
</span><span class='line'>Finished processing 1 / 1 hosts in 856.85 ms</span></code></pre></td></tr></table></div></figure>


<p>Instalando um pacote em todos os nodes</p>

<pre><code>mco rpc package install package=htop
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Discovering hosts using the mc method for 2 second(s) .... 2
</span><span class='line'>
</span><span class='line'> * [ ============================================================&gt; ] 2 / 2
</span><span class='line'>
</span><span class='line'>Summary of Ensure:
</span><span class='line'>
</span><span class='line'>   0.8.3-1 = 2
</span><span class='line'>
</span><span class='line'>Finished processing 2 / 2 hosts in 4972.04 ms</span></code></pre></td></tr></table></div></figure>


<h4>8.3.2 plugin package: uninstall</h4>

<p>Removendo um pacote de um node específico</p>

<pre><code>mco rpc package uninstall package=htop -I debian.hacklab
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class=''><span class='line'> * [ ============================================================&gt; ] 1 / 1
</span><span class='line'>
</span><span class='line'>Summary of Ensure:
</span><span class='line'>
</span><span class='line'>   absent = 1
</span><span class='line'>
</span><span class='line'>Finished processing 1 / 1 hosts in 7515.24 ms</span></code></pre></td></tr></table></div></figure>


<p>Removendo um pacote em todos os nodes</p>

<pre><code>mco rpc package uninstall package=htop
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Discovering hosts using the mc method for 2 second(s) .... 2
</span><span class='line'>
</span><span class='line'> * [ ============================================================&gt; ] 2 / 2
</span><span class='line'>
</span><span class='line'>Summary of Ensure:
</span><span class='line'>
</span><span class='line'>   absent = 2
</span><span class='line'>
</span><span class='line'>Finished processing 2 / 2 hosts in 4230.82 ms</span></code></pre></td></tr></table></div></figure>


<h4>8.3.3 plugin package: status</h4>

<p>Verificando o status de um pacote em um node específico</p>

<pre><code>mco rpc package status package=htop -I debian.hacklab
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
</pre></td><td class='code'><pre><code class=''><span class='line'> * [ ============================================================&gt; ] 1 / 1
</span><span class='line'>
</span><span class='line'>debian.hacklab                           
</span><span class='line'>       Arch: nil
</span><span class='line'>    desired: install
</span><span class='line'>     Ensure: 0.8.3-1
</span><span class='line'>      Epoch: nil
</span><span class='line'>      error: ok
</span><span class='line'>       Name: htop
</span><span class='line'>     Output: nil
</span><span class='line'>   Provider: :apt
</span><span class='line'>    Release: nil
</span><span class='line'>     status: installed
</span><span class='line'>    Version: nil
</span><span class='line'>
</span><span class='line'>Summary of Arch:
</span><span class='line'>
</span><span class='line'>     No aggregate summary could be computed
</span><span class='line'>
</span><span class='line'>Summary of Ensure:
</span><span class='line'>
</span><span class='line'>   0.8.3-1 = 1
</span><span class='line'>
</span><span class='line'>Finished processing 1 / 1 hosts in 391.55 ms</span></code></pre></td></tr></table></div></figure>


<p>Verificando o status de um pacote em todos os nodes</p>

<pre><code>mco rpc package status package=htop
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Discovering hosts using the mc method for 2 second(s) .... 2
</span><span class='line'>
</span><span class='line'> * [ ============================================================&gt; ] 2 / 2
</span><span class='line'>
</span><span class='line'>debian.hacklab                           
</span><span class='line'>       Arch: nil
</span><span class='line'>    desired: install
</span><span class='line'>     Ensure: 0.8.3-1
</span><span class='line'>      Epoch: nil
</span><span class='line'>      error: ok
</span><span class='line'>       Name: htop
</span><span class='line'>     Output: nil
</span><span class='line'>   Provider: :apt
</span><span class='line'>    Release: nil
</span><span class='line'>     status: installed
</span><span class='line'>    Version: nil
</span><span class='line'>
</span><span class='line'>puppet.hacklab                           
</span><span class='line'>       Arch: nil
</span><span class='line'>    desired: install
</span><span class='line'>     Ensure: 0.8.3-1
</span><span class='line'>      Epoch: nil
</span><span class='line'>      error: ok
</span><span class='line'>       Name: htop
</span><span class='line'>     Output: nil
</span><span class='line'>   Provider: :apt
</span><span class='line'>    Release: nil
</span><span class='line'>     status: installed
</span><span class='line'>    Version: nil
</span><span class='line'>
</span><span class='line'>Summary of Arch:
</span><span class='line'>
</span><span class='line'>     No aggregate summary could be computed
</span><span class='line'>
</span><span class='line'>Summary of Ensure:
</span><span class='line'>
</span><span class='line'>   0.8.3-1 = 2
</span><span class='line'>
</span><span class='line'>Finished processing 2 / 2 hosts in 174.41 ms</span></code></pre></td></tr></table></div></figure>


<h4>8.3.4 plugin package: update</h4>

<p>Atualizando um pacote em um node específico</p>

<pre><code>mco rpc package update package=facter -I debian.hacklab
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>
</span><span class='line'> * [ ============================================================&gt; ] 1 / 1
</span><span class='line'>
</span><span class='line'>Summary of Ensure:
</span><span class='line'>
</span><span class='line'>   1.6.17-1puppetlabs1 = 1
</span><span class='line'>
</span><span class='line'>
</span><span class='line'>Finished processing 1 / 1 hosts in 11307.56 ms</span></code></pre></td></tr></table></div></figure>


<p>Atualizando um pacote em todos os nodes</p>

<pre><code>mco rpc package update package=htop
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Discovering hosts using the mc method for 2 second(s) .... 2
</span><span class='line'>
</span><span class='line'> * [ ============================================================&gt; ] 2 / 2
</span><span class='line'>
</span><span class='line'>Summary of Ensure:
</span><span class='line'>
</span><span class='line'>   0.8.3-1 = 2
</span><span class='line'>
</span><span class='line'>Finished processing 2 / 2 hosts in 2999.96 ms</span></code></pre></td></tr></table></div></figure>


<h3>8.4 Agente facter facts</h3>

<p>O Mcollective possui suporte a mostrar certos fatos do sistema, mas se quisermos utilizar os fatos do facter, precisamos fazer alguns ajustes na configuração e adicionar um plugin manualmente, isto é necessário pois infelizmente o plugin <strong>facter facts</strong> não está empacotado para o debian.</p>

<p>Acesse do diretório tmp</p>

<pre><code>cd /tmp
</code></pre>

<p>Faça o clone do repo mcollective-plugins</p>

<pre><code>git clone https://github.com/puppetlabs/mcollective-plugins.git
</code></pre>

<p>Copie o plugin para o diretório do mcollective</p>

<pre><code>cp mcollective-plugins/facts/facter/facter_facts.rb /usr/share/mcollective/plugins/mcollective/facts/
</code></pre>

<p>Ajuste o arquivo client.cfg e server.cfg do mcollective, remova ou comente o trecho abaixo</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class=''><span class='line'># Facts
</span><span class='line'>factsource = yaml
</span><span class='line'>plugin.yaml = /etc/mcollective/facts.yaml</span></code></pre></td></tr></table></div></figure>


<p>E insira o seguinte no lugar</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
</pre></td><td class='code'><pre><code class=''><span class='line'># Facts
</span><span class='line'>factsource = facter</span></code></pre></td></tr></table></div></figure>


<p>Após alterar, reinicie o mcollective</p>

<pre><code>/etc/init.d/mcollective restart
</code></pre>

<p>Consulte o fato virtual em um node específico</p>

<pre><code>mco facts virtual  -v -I debian.hacklab
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Report for fact: virtual
</span><span class='line'>
</span><span class='line'>        virtualbox                              found 1 times
</span><span class='line'>
</span><span class='line'>            debian.hacklab
</span><span class='line'>
</span><span class='line'>
</span><span class='line'>---- rpc stats ----
</span><span class='line'>           Nodes: 1 / 1
</span><span class='line'>     Pass / Fail: 1 / 0
</span><span class='line'>      Start Time: Wed Feb 06 20:57:39 -0200 2013
</span><span class='line'>  Discovery Time: 0.00ms
</span><span class='line'>      Agent Time: 136.37ms
</span><span class='line'>      Total Time: 136.37ms    </span></code></pre></td></tr></table></div></figure>


<p>Consulte o fato ipaddress do facter em todos os nodes</p>

<pre><code>mco facts ipaddress -v
</code></pre>

<p>Acompanhe a saída</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Discovering hosts using the mc method for 2 second(s) .... 2
</span><span class='line'>Report for fact: ipaddress
</span><span class='line'>
</span><span class='line'>        192.168.56.50                           found 1 times
</span><span class='line'>
</span><span class='line'>            puppet.hacklab
</span><span class='line'>
</span><span class='line'>        192.168.56.51                           found 1 times
</span><span class='line'>
</span><span class='line'>            debian.hacklab
</span><span class='line'>
</span><span class='line'>---- rpc stats ----
</span><span class='line'>           Nodes: 2 / 2
</span><span class='line'>     Pass / Fail: 2 / 0
</span><span class='line'>      Start Time: Wed Feb 06 20:52:29 -0200 2013
</span><span class='line'>  Discovery Time: 2007.25ms
</span><span class='line'>      Agent Time: 54.72ms
</span><span class='line'>      Total Time: 2061.97ms</span></code></pre></td></tr></table></div></figure>


<p>Consulte o fato kernelversion do facter em todos os nodes</p>

<pre><code>mco facts kernelversion -v
</code></pre>

<p>Acompanhe a saída:</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>Discovering hosts using the mc method for 2 second(s) .... 2
</span><span class='line'>Report for fact: kernelversion
</span><span class='line'>
</span><span class='line'>        2.6.32                                  found 2 times
</span><span class='line'>
</span><span class='line'>            debian.hacklab
</span><span class='line'>            puppet.hacklab
</span><span class='line'>
</span><span class='line'>
</span><span class='line'>---- rpc stats ----
</span><span class='line'>           Nodes: 2 / 2
</span><span class='line'>     Pass / Fail: 2 / 0
</span><span class='line'>      Start Time: Wed Feb 06 20:52:47 -0200 2013
</span><span class='line'>  Discovery Time: 2008.67ms
</span><span class='line'>      Agent Time: 59.92ms
</span><span class='line'>      Total Time: 2068.59ms</span></code></pre></td></tr></table></div></figure>


<p>Podemos ver que o MCO está conseguindo trazer os fatos do facter corretamente.</p>

<h2>9. Amarrando as pontas</h2>

<p>Essa foi uma instalação básica do Mcollective em ambiente debian - usando RabbitMQ, além disto, apresentei alguns comandos iniciais usando o agente/client puppet criado pela Puppetlabs para o MCO.</p>

<p>Mas não pense que é só isto, ele é muito mais poderoso, existem diversos outros agentes para utilizar e você pode construir seus próprios agentes usando RPC se achar necessário, e ainda existem os plugins em ruby, ele é muito extensível.</p>

<p>Vale comentar que apesar de ter utilizado o RabbitMQ, o criador do MCO recomenda o uso do ActiveMQ a partir da versão 2.x.x, aparentemente alguns dos recursos desta versão só irão funcionar com o ActiveMQ. Em breve espero tratar o uso do ActiveMQ também.</p>

<p>Preciso explicar que esse post apenas agrupa o que eu estudei até o momento, a partir daqui é hora de aprofundar ainda mais.</p>

<h2>10. Referências</h2>

<p><strong>Plugins Github</strong> <br></p>

<ul>
<li>https://github.com/puppetlabs/mcollective-plugins</li>
<li>https://github.com/puppetlabs/mcollective-puppet-agent#readme</li>
</ul>


<p><strong>Introdução ao MCO</strong> <br></p>

<ul>
<li>https://puppetlabs.com/mcollective/introduction/</li>
<li>http://docs.puppetlabs.com/mcollective/reference/basic/gettingstarted_debian.html</li>
<li>http://docs.puppetlabs.com/mcollective/reference/basic/gettingstarted.html</li>
<li>http://docs.puppetlabs.com/mcollective/reference/basic/configuration.html</li>
</ul>


<p><strong>Construindo Agentes e Clientes com SimpleRPC</strong> <br></p>

<ul>
<li>http://docs.puppetlabs.com/mcollective/simplerpc/</li>
</ul>


<p><strong>Slides MCO</strong> <br></p>

<ul>
<li>http://www.slideshare.net/PuppetLabs/presentation-16281121</li>
</ul>


<p><strong>RabbitMQ</strong> <br></p>

<ul>
<li>http://www.rabbitmq.com/stomp.html</li>
</ul>


<p>O livro <strong>Pro Puppet</strong> da Puppetlabs também foi uma ótima referência de estudo.</p>

<p>[s]<br>
Guto</p>
]]></content>
  </entry>
  
</feed>
