Arquivo da tag: vagrant

Como usar o Vagrant.has_plugin? no Vagrantfile

Olá, pessoal!

Esse artigo é uma continuação do Vagrant e seus plugins, de outubro de 2013, e, para falar a verdade, começou a ser escrito antes do original. É que percebi que, sem uma explicação mais básica do que eram os plugins, ia “faltar base” – como dizia um professor do cursinho!. Então, mais uma vez, se quiser primeiro saber o que são os plugins no Vagrant, leia o artigo original primeiro, ok?

vagrant-has-plugin

O que é o método Vagrant.has_plugin?

O has_plugin? é um método da API do Vagrant, para ser usado no seu Vagrantfile, que verifica se um plugin está disponível no sistema. Com o grande número de plugins disponíveis (confira os listados na wiki oficial), é importante ter uma forma de garantir que quem for usar seu projeto Vagrant tenha os plugins que você definiu/utilizou, e, se não tiver, fazer algo com essa informação.

Vamos ver um exemplo para deixar mais fácil o entendimento:

Nesse trecho acima vemos um Vagrantfile que utiliza o plugin vagrant-cachier para acelerar o vagrant up se o usuário tem o plugin instalado na máquina, e, caso não tenha, tudo continua funcionando, apenas sem a aceleração. Sem usar o has_plugin? o Vagrant interromperia o processo com uma mensagem de erro.

Parece bastante com o conceito de progressive enhancement/graceful degradation: forneça ao usuário que tem apenas o requisito básico uma versão funcional do seu projeto, sem traumas. E, para os que tem mais requisitos (no caso o plugin que definimos), entregue também as funções melhoradas (nesse caso, uma camada de cache que vai acelerar o provisionamento das máquinas virtuais. Se você ainda não conhece o vagrant-cachier, do brasileiro Fabio Rehm, ou @fgrehm, é uma boa hora de começar!).

Um outro exemplo segue abaixo:

Nesse caso, ao contrário do anterior, é feita uma ação quando um plugin não existe no sistema. E quando que isso é útil? Principalmente para os casos que onde precisamos avisar para o usuário que um plugin é necessário/recomendável para executar a aplicação, dando algum caminho para que ele possa resolver a situação. No exemplo acima, avisamos que o projeto está usando o plugin vagrant-bindler para fazer a gestão dos plugins e passamos um caminho para que o usuário faça a instalação do mesmo se ele ainda não tiver (plugin também criado pelo @fgrehm).

Há tempos… um problema!

A função Vagrant.has_plugin? foi introduzida no Vagrant na versão 1.3.0, com alguns problemas, e na versão 1.3.2 foi realmente consertada, isso tudo em setembro de 2013. Mas por que então, mesmo tendo uma certa idade, essa função ainda não é tão utilizada?

Isso acontece por uma pequena inconsistência na implementação dessa API, que faz com que o nome do plugin internamente para o Vagrant (que vai ser usada na chamada Vagrant.has_plugin?) seja diferente do nome do plugin que é usado na instalação via linha de comando $ vagrant plugin install ....

Antes de perceber isso acima, eu mesmo no começo não conseguia entender a lógica, que parecia ser tão simples: fazer uma condição ruby IF ou UNLESS, passando o nome do plugin. Por que não funcionava? Era essa bendita inconsistência de nomes. Ainda bem que não desisti de entender!

Para facilitar, vamos chamar esses nomes da seguinte forma:

  • nome de instalação do plugin: usado no comando $ vagrant plugin install ....
  • nome interno do plugin: usado no Vagrantfile, com o método has_plugin?

Com isso em mente, vamos para os  exemplos:

Quando acessamos a lista oficial dos plugins disponíveis para Vagrant lá não encontramos o nome interno (ainda, estou trabalhando nisso :-) ); apenas aparece o nome de instalação. Uma diferença que, às vezes, é apenas de maíusculas ou minúsculas entre os nomes das duas versões mas que já atrapalha tudo!

Peguemos o Bindler. Para instalá-lo no sistema, é usado o nome da Gem (em minúsculas):

$ vagrant plugin install bindler

Já para usar no seu Vagrantfile, com o has_plugin?, tem que ser o nome interno do plugin (começando com maíscula):

Vagrant.has_plugin?("Bindler")

É, realmente é complicado. Por não haver um padrão, é possível encontrar todos os tipos de combinações: nomes iguais, totalmente diferentes ou apenas a diferença de capitulares. Mas existe uma solução! Vamos vê-la?

A solução!

E a solução é: aprender a ler o repositório do plugin! Puxa, não é o que você estava esperando, não é mesmo… É, por enquanto (dezembro de 2013), não existe uma solução perfeita, por isso vamos aprender aqui a ler o repositório sempre que você precisar.

Arquivos importantes

O primeiro passo é saber localizar, dentro de um repositório, o nome de instalação do plugin e o nome interno do plugin:

  • /nome-de-instalação-do-plugin.gemspec: é nesse arquivo que temos o nome de instalação. O arquivo fica na pasta raiz do repositório do plugin. Exemplos: bindler.gemspec, vagrant-aws.gemspec, vagrant-cachier.gemspec etc.
  • /lib/nome-de-instalação-do-plugin/plugin.rb: é nesse arquivo que temos o nome interno. O arquivo fica no terceiro nível do repositório do plugin. Dentro desse arquivo, existe um atributo name, que é o nome interno que você vai usar. Exemplos para os mesmos plugins acima: BindlerAWSvagrant-cachier.

Achar o repositório do plugin

O segundo passo é saber onde está o repositório do plugin. Minha sugestão, comece pela lista oficial, e siga o link de lá. Na maioria das vezes, você vai cair num repositório no GitHub (ou em algum outro serviço de hospedagem de projetos open source).

A partir daí é só navegar buscando os arquivos mostrados ali em cima, que você já terá a informação necessária para trabalhar.

Considerações finais

Vimos que o Vagrant.has_plugin? é um método da API do Vagrant muito útil para utilizar nos seus projetos. Principalmente importante para os projetos compartilhados com muitas pessoas, verificando em tempo de execução a existência ou não de um plugin determinado, permitindo que quem tenha o plugin aproveite as funcionalidades, mas não impedindo que os usuários sem o plugin tenham uma experiência pelo menos básica.

Entendemos também que existem dois nomes para os plugins: o nome de instalação e o nome interno, e qual deles deve ser usado junto com o Vagrant.has_plugin?. Aprendemos quando usar cada um deles, e como descobrir o nome lendo o repositório do plugin (fique de olho na wiki da lista oficial de plugins, pois vou fazer um trabalho visando facilitar a pesquisa centralizada desses nomes, seria interessante, certo?).

Quer uma dica de plugins para começar a trabalhar? Dê uma olhada no meu artigo original, Vagrant e seus plugins, que tem algumas opções que já utilizo. Agora é sua vez de montar uma estratégia de uso dos plugins e do has_plugin? nos seus projetos Vagrant e

Fique à vontade para tirar suas dúvidas nos comentários (ou me procure, estou em quase todo lugar na internet como rogeriopradoj, é só chamar!)

Feliz vagrant up!

Referências:

[1] https://github.com/fgrehm/bindler/issues/22

[2] https://gist.github.com/rogeriopradoj/6954261

[3] https://github.com/mitchellh/vagrant/wiki/Available-Vagrant-Plugins

 

Vagrant e seus plugins

E lá vamos nós falar de Vagrant!

vagrant-e-seus-plugins

Resumo da história dos plugins no Vagrant

Os plugins viraram cidadões de primeira classe na API v2 do Vagrant (antes eles até eram suportados com um pouco de mágica e um monte de requires no meio do seu Vagrantfile). Agora, como o Mitchell Hashimoto diz, o próprio Vagrant usa a API de plugins interna para boa parte de suas implementações, por isso, é possível ficar mais tranquilo de que as coisas funcionarão e que a interface é estável e bem suportada.

Não tenho nenhum plugin ainda desenvolvido, mas já utilizo vários para facilitar meu trabalho com o Vagrant. Então, vamos conhecer um pouco mais?

Como instalar plugins no Vagrant

A documentação do Vagrant sobre plugins está bem completa nesse ponto, e é bem fácil: nada mais do que rodar: $ vagrant plugin install NOME-DO-PLUGIN.

Exemplo para instalar o vagrant-aws:

$ vagrant plugin install vagrant-aws.

Os plugins são na maioria mantidos pela comunidade, e por isso não existe uma listagem oficial. No entanto, existe uma página na wiki do projeto com os plugins marcados pelos usuários, sugiro que visite para buscar os que sirvam para o seu caso de uso.

Quer uma dica de alguns para começar? Veja abaixo:

Plugins Vagrant que não podem faltar para mim

Bindler

Para quem conhece o Composer no mundo PHP, o Bundler no mundo Ruby ou o Bower no mundo FrontEnd, é fácil entender o que esse plugin faz e também a vantagem de usá-lo, o Bindler.

Ele permite que você crie um arquivo na raiz do seu projeto Vagrant (na mesma pasta onde você coloca o seu Vagrantfile) para distribuição, deixando claro para seus usuários que plugins são as suas dependências.

Quando alguém for usar o seu projeto, executará $ vagrant plugin bundle antes do $ vagrant up, e o Bindler se encarregará de instalar as dependências que faltarem. Se o usuário já tiver os plugins instalado globalmente, estes serão usados, senão, o Bindler instalará o que faltar localmente para o projeto apenas. E quando o usuário fizer o $ vagrant destroy tudo voltará ao que era antes.

Vagrant Cachier

O Cachier é aquele cara que faz você se perguntar: como conseguiu viver sem ele até agora! Ele faz o cache dos pacotes Apt que você instala na suas distribuições Debian-like (Ubuntu inclusive) entre todas os projetos que você tiver baseado em uma box.

Assim, ele acelera (e muito!!!) a instalação das suas dependências, pois, se um pacote já tiver sido baixado naquela versão específica em um outro projeto, será usado o cache em vez de ir até o repositório oficial do Ubuntu, por exemplo.

Vagrant HostManager

Vai chegar o momento em que apenas definir um IP na opção :private_network do Vagrantfile, ou mesmo a redirecionamento de porta via :forwarded_port, não será mais suficiente para testar seu projeto (por diversos motivos isso pode acontecer. Acredite, quando você chegar nesse nível você vai lembrar das minhas palavras ;-) ).

Nesse momento você vai procurar uma forma de configurar o seu arquivo HOSTS, /etc/hosts (nos sistemas *nix) ou %windir%\system32\drivers\etc\hosts (no Windows), para que endereço do seu Vhost do Apache fique disponível tanto internamente nas máquinas (Guests) quanto a partir do seu sistema principal (Host). Qual é o caminho normal para fazer isso? Sim, editar manualmente seu arquivo HOST em um monte de lugares.

Aí que entra o plugin HostManager: com base numa pequena configuração do seu Vagrantfile ele já configura tudo isso para você. Existem alguns outros que fazem o serviço de forma parecida, mas foi com ele que me adaptei mais.

Considerações finais

Os plugins foram uma inclusão importante no ecossistema do Vagrant, e como viram, não é difícil de usar os que já estão disponíveis. Esse artigo está longe de te dar o caminho completo para usar as ferramentas, mas já te inicia e mostra onde você pode conseguir mais informações. Procure conhecer e testar o máximo que você conseguir pois assim vai ser fácil de tomar a decisão de usar ou não um deles em seus futuros projetos.

E fique a vontade de usar os comentários se quiser ajuda!

Até mais!

Este artigo foi publicado originalmente em RogerioPradoJ.com.

Vagrant: O que, Por que e Como

Tradução livre de Vagrant: What, Why, and How, disponível em http://net.tutsplus.com/tutorials/php/vagrant-what-why-and-how/.

Este artigo te ajudará a usar o Vagrant para administrar suas instâncias de máquinas virtuais e explicará como se beneficiar do Puppet para fazer a provisão de vários recursos como o PHP e o PostgreSQL.

garoto propaganda do vagrant
Garoto propaganda :-) da ferramenta Vagrant – http://vagrantup.com

Introdução

Os desenvolvedores tem à disposição um grande número de maneiras de construir seu ambiente de desenvolvimento web. Podem ser usadas opções “locais”, do tipo dos servidores “tudo em um”como o Zend Server, XAMPP, MAMP, WAMP etc; ou ainda como você instalando os componentes a partir dos fontes ou via um sistema de gerenciamento de pacotes, como o Homebrew, o Apt ou o Yum.

Isso vai se acumulando a medida que você trabalha em vários projetos diferentes: PHP 5.3 e PHP 5.4, MySQL, SQLite, MongoDB, Postgres, PEAR, PHPUnit, Rails 3.1, Memcached, Redis, Gearman, NodeJS etc. E se você precisar  atualizar seu computador se ele pifar, você terá que começar tudo de novo.

Pode ser usada uma configuração “remota”, com um servidor com compartilhamentos “Samba” ou um servidor SSH montado com uma ferramenta como o ExpanDrive. A última opção esbarra na latência de leitura e escrita dos arquivos, que é extremamente chata. É possível usar o SSH com o Vim para tudo, o que é rápido, mas só funciona se você quiser usar o Vim para tudo também.

Desenvolvimento vs Produção

Mesmo que você esteja feliz com a forma que vem fazendo as coisas até agora, quantas vezes você já ouviu (ou disse) “Bem, está funcionando no meu computador”?

Isso é terrivelmente comum e acontece quando os ambientes diferem até mesmo nos detalhes mais triviais.

É extremamente importante garantir que seu ambiente de desenvolvimento seja idêntico ao ambiente de produção, e que ele também corresponda ao servidores de staging e de teste se esses existirem.

Isso pode parecer fácil se você pensar apenas na instalação do Apache, do PHP de alguma cópia do MySQL, porém existem milhões de fatores para avaliar. Se você estiver desenvolvendo no OSX e fazendo deploy num sistema Ubuntu, então você deve se deparar com problemas estranhos relacionados a maiúsculas. Isso é comum no CodeIgniter, quando alguém cria uma biblioteca com a primeira letra minúscula. Ela irá carregar corretamente no OSX, mas irá quebrar quando for implementada na produção. Seu processo de desenvolvimento pode ter feito você perder alguns contratos só por causa de algumas diferenças triviais entre sistemas operacionais que ninguém notou até ser muito tarde.

Desenvolvimento = Produção

Então qual é a solução? Forçar que todos os desenvolvedores joguem fora suas ferramentas e trabalhem todos no mesmo modelo de laptop? Se os seus colegas ganharem Macbooks novinhos em folha talvez você não ouça muitas reclamações, mas você teria que usar o OSX Server para tudo.

Você poderia usar o Linux para tudo, mas entraria numa briga para decidir qual distribuição utilizar. Forçar os desenvolvedores para usar o mesmo sistema operacional gera problemas, reduz a produtividade e promove lutas de nerds.

A virtualização é a resposta e isto não é nada novo, mas geralmente quando pensamos em virtualização pensamos nos problemas de performance e nas ventoinhas girando que nem malucas enquanto o sistema tenta rodar dois sistemas operacionais ao mesmo tempo.

Essa situação pode ser verdade quando tentamos rodar o Windows em uma máquina não muito potente mas, hoje em dia, um Mac mediano com 4 GB de RAM de fábrica é mais do que suficiente para rodar uma instalação de um servidor Ubuntu em modo de linha de comando com todas ferramentas habituais (IDE, browser, ferramentas de depuração etc.). Existem diferentes versões de virtualização, mas eu prefiro o VirtualBox da Oracle (que é grátis). Esse programa faz o “trabalho pesado” da virtualização, enquanto a ferramenta Vagrant serve para gerenciar as instâncias.

Passo 1 – Instalando o VirtualBox

Primeiro, baixe e instale o VirtualBox. Nos sistemas *nix (Mac OSX, Linux etc.) você precisará alterar seu .bash_profile (ou .zsh_profile) para estender a variável $PATH:

Isso permitirá que o Vagrant saiba onde o VirtualBox está instalado e, é claro, será diferente em cada sistema operacional.

Passo 2 - Instalando o Vagrant

Você pode baixar um binário do vagrant para o seu sistema operacional, ou instalar ele como uma gem se não houver um binário disponível:

Passo 3 - Criando uma Instância

Crie um lugar para suas configurações ficarem:

Iremos usar o Ubuntu 12.04 LTS (Precise Pangolin), o qual já tem uma “box” configurada.

Aqui você enxerga o argumento “precise32″, que é o apelido da URL. Agora você pode criar a instância que irá baixar o arquivo .box.

Agora ela estará rodando. Fácil! Se você quiser acessar a instância via SSH, use este comando:

Passo 4 - Configuração

Você terá um arquivo, chamado Vagrantfile, que conterá a configuração dessa instância:

Essa é, se você ainda não notou, sintaxe Ruby; por isso você pode ser bem criativo com o arquivo, apesar de aqui só termos o básico.

Ele mostra qual apelido usar, e tem a URL para o caso do apelido não estar definido localmente (útil para casos de compartilhamento).

As linhas share_folder são bem úteis para mapear pastas da instância com pastas locais. Usando nfs => true a instância será capaz de escrever e alterar permissões dos arquivos, o que é útil se você estiver, por exemplo, tentando instalar um CMS ali.

O redirecionamento de portas permite que você acesse sua instância em http://localhost:8080 e, é claro, faça alterações para diferentes portas em caso de conflito.

Esse arquivo de configuração também define o fuso horário para Europe/London, depois executa o apt-get update, que força seu sistema para se atualizar toda vez que ele é iniciado. Se você pular esse item da configuração, pode encontrar vários pacotes se recusando a instalar pois as referências estão desatualizadas.

Quando você alterar a configuração, pode recarregar a instância para utilizá-la:

Agora que nossos servidores estão no ar e prontos para continuar, precisamos instalar neles alguns softwares. Não vamos só rodar o apt-get install em um monte de pacotes na linha de comando, vamos “provisionar” nossos servidores.

Passo 5 - Provisionamento

O provisionamento ou configuração do servidor não é algo que a maioria dos desenvolvedores pensam a respeito pois isso é feito normalmente pelos sysadmins. A ideia é criar algum registro do que software e configurações foram postas em um servidor assim você poderia criar novos ambientes de desenvolvimento, novos servidores staging que replicam os servidores de produção ou então criar outro servidor de produção para fazer balanceamento de carga entre eles.

Provisionamento das antigas

Como os sysadmins lidam com isso varia, mas no passado foram usados todos os tipos de solução – desde manter uma wiki dos comandos que foram executados (o que pode ficar grande e obsoleto rapidamente) e o maravilhoso método de manter um “multi-terminal”, onde você digita os comandos em uma janela e ele replica os mesmos comandos para outros 7 servidores ao mesmo tempo. Todos esses métodos são terríveis.

Uma solução seria criar o seu próprio arquivo .box ou criar um backups .iso assim novos servidores poderiam ser baseados neles; no entanto manter essas imagens gera um monte de trabalho extra e não importa o quanto você tente, essas máquinas de desenvolvimento se tornarão obsoletas com o tempo.

Provisionamento moderno

Existem atualmente dois sistemas populares, o Puppet e o Chef. Ambos existem há anos, mas começaram a se tornar bem populares com o aumento do uso método de desenvolvimento DevOps. As ideias dos dois são parecidas e você deveria estudar os dois sistemas, mas aqui no tutorial iremos nos focar exclusivamente no Puppet.

Basicamente, em vez de rodar um série de comandos e torcer para que tudo dê certo, você criará um manifesto para o Puppet explicando tudo o que você precisar garantir que tenha sido feito. Quando você roda um comando no terminal, você está basicamente dizendo ao computador:

“Instale o Apache”

Com o Puppet você diria:

“Garanta que o Apache está instalado”

Ou, em vez de:

“Crie uma nova pasta, chame-a de /var/www e defina a permissão para www-data:www-data”

Com o Puppet diríamos:

“Garanta que exista /var/www e que tenha permissões que correspondam com www-data:www-data”

A diferença aqui é que esses manifestos podem ser executados múltiplas vezes (em um cron job a cada hora ou diariamente) para deixar tudo atualizado, e não haverá resultados inesperados de algo tentando ser instalado duas vezes.

Ele também irá testar se tudo está rodando como esperado, pois se alguma dessas regras falhar serão emitidos erros que são mais fáceis de rastrear do que rodar o grep numa grande quantidade de resultados de comandos bash. O Puppet irá mostrar erros grandes e vermelhos que deixarão você saber se o PHP não foi instalado ou um módulo específico não puder ser configurado.

Manifestos e Módulos

Os manifestos são um pouco confusos no início, mas depois de um tempo, eles começam a fazer sentido.

Para revisar um exemplo básico:

Não é preciso explicar o que está acontecendo aqui, certo?

Esse arquivo pode ser referenciado mais para a frente no seu manifesto como “testfile”, o que indica que ele pode ser listado como uma dependência para outras ações.

Para exemplos mais complexos, vamos referenciar o os manifestos Puppet do PyroCMS no GitHub.

Ele inclui o módulo “apache”, define algumas variáveis, executa o manifesto extra “apache:php” no módulo apache, cria um virtual host e garante que o “mod_rewrite” está habilitado.

Todas essas classes são definidas no módulo Apache que incluímos.

Continuando, também queremos instalar o PHP:

Esse trecho do manifesto irá instalar as extensões PHP que precisamos e depois a opção notify informará ao Apache que você instalou novas configurações, indicando que ele deve reiniciar.

Aqui será configurado um servidor postgres, criado um banco de dados chamado “pyrocms” e garantir que exista um usuário “pyrocms” com a senha informada.

Perto do fim! O último passo é garantir que você tenha arquivos e pastas com permissões de escrita definidos corretamente:

Isso irá garantir que exista um document root do Apache, que o arquivo de configuração esteja configurado como 0666 e que algumas pastas estejam como 777.

E aí temos tudo!

Se tudo funcionou corretamente, você deve estar vendo vários linhas de texto azul sinalizando cada coisa que está sendo instalada mas, se algo der errado, verá linhas vermelhas. Pesquise no Google sobre esses erros e tente novamente.

Os módulos usados aqui são: Apache, Postgres e PHP, e você pode ver tudo em ação clonando o repositório Vagrant do PyroCMS:

Aponte seu navegador para http://localhost:8089/ e você deve enxergar o instalador. Bem fácil, não?

Nota: Será instalado o MySQL pois o suporte ao Postgres e ao SQLite no PyroCMS ainda está em desenvolvimento, esperando algumas funcionalidades PDO ficarem prontas no CodeIgniter. Se você estiver interessado, pode experimentar alterar o Vagrantfile para usar o manifesto ubuntu-apache2-pgsql-php5.pp, destruir a instância e em seguida iniciá-la novamente. O submódulo pyrocms também precisará de um checkout do git em feature/pdo.

Sumário

Nesse artigo, usamos o Vagrant, o VirtualBox e o Puppet para, não apenas configurar uma instância de um servidor para trabalharmos, mas criarmos um suite de testes para nosso servidor garantir que tudo esteja corretamente executando, instalado e configurado.

Também criamos um checklist para os requisitos e, no futuro, poderemos criar qualquer número de servidores iguais a esse em minutos, e não em horas!

Este artigo foi publicado originalmente em RogerioPradoJ.com.

Documentação em português do Brasil (pt_BR) do Vagrant

Olá, pessoal.

Até para ajudar na minha palestra no TDC2012, comecei o projeto de tradução da documentação do Vagrant para português do Brasil (pt_BR, pt-BR, pt-br etc etc etc).

Seguem links:

garoto propaganda do vagrant
Garoto propaganda :-) da ferramenta Vagrant – http://vagrantup.com

Até mais!

Este artigo foi publicado originalmente em RogerioPradoJ.com.

Vou palestrar na TDC 2012, Desenvolvimento PHP com Vagrant

Olá, pessoal,

TDC 2012 - Logo

Já está em cima da hora, mas nesse sábado, 07/07/2012, vou ser palestrante no evento TDC – The Developer’s Conference.

TDC São Paulo 2012 - Trilha PHP - Logo

Minha palestra, será dentro da Trilha PHP e abordará como utilizar a ferramenta Vagrant para criar uma ambiente de desenvolvimento PHP com máquinas virtuais de forma fácil.

PHP - Logo + Vagrant Logo

Aproveito para agradecer ao Grupo de Usuários PHPSP, tanto à coordenação que acreditou na palestra e aceitou que eu palestrasse, quanto à própria comunidade que têm tantos profissionais brilhantes que me motivam sempre a buscar aperfeiçoamento.

Diga nos comentários se você já usa ambientes de desenvolvimento virtualizados no seu dia a dia, e se já conhece a ferramenta Vagrant.

Até mais!