# Busine.me
### 1. Introdução
#### 1.1 Visão Geral

Esse documento irá descrever e especificar o plano de gerência de configuração que será aplicado no projeto Busine.me Web. O projeto se trata de um aplicativo que pretende resolver problemas de mobilidade urbana, e está sendo desenvolvido nas disciplinas de GPP e MDS da Universidade de Brasilia. A wiki do projeto pode ser acessada a partir do seguinte link:
http://lappis.unb.br/redm/projects/grupo-2-busine-me/wiki
Na wiki é possível ver documentação de Visão do projeto, arquitetura, casos de uso etc. A documentação do projeto também está em desenvolvimento.
O repositório de desenvolvimento da disciplina MDS pode ser encontrado no seguinte link:
https://github.com/aldarionsevero/BusinemeWeb
O repositório oficial do aplicativo pode ser encontrado nesse outro link:
https://github.com/Busineme/BusinemeWeb
Por ser um aplicativo que começou seu desnvolvimeno nesse semestre (2015/1), o mesmo da confecção desse documento, várias abordagens e melhorias de GCS podem ser feitas para, tanto facilitar o desenvolvimento, quanto facilitar manutenção e implantação.

#### 1.2 Propósito

Com o plano proposto por esse documento, espera-se que melhorias significativas com relação a Gerência de configuração de Software sejam assimiladas pelo software Busine.me Web. A metodologia proposta por esse plano será desenvolvida e implantada durante 2 meses da disciplina de GCS, juntamente com o desenvolvimento do software das diciplinas de MDS e GPP, mas após esses dois meses essas melhorias continuarão trazendo as melhorias propostas enquanto elas estiverem sendo utilizadas. A disciplina de MDS requere que seus projetos tenham versionamento e controle de mudança, que tenha testes e razoável cobertura, logo essa parte fica fora do escopo deste documento. Assim sendo, integração contínua e Automação de implantação passa a ser o escopo real da metodologia proposta nesse documento.

#### 1.3 Escopo

O escopo do projeto abrange as seguintes demandas para o software:
* Automação de testes e de builds por meio de integração contínua utilizando Travis
* Automação de implantação utilizando a ferramenta Chef
* Para auxiliar o Travis utilizaremos a ferramenta Fabric ou Chake para executar comandos em máquinas remotas auxiliando a implantação automática.
* Garantir localmente o mesmo ambiente versionado com a ferramenta Vagrant, evitando problemas de quebras ao utilizar localhost.

#### 1.4 Definições, Acrônimos e Abreviações

| Abreviação | Significado |
| GCS | Gerência de Configuração de Software |
| MDS | Método de Desenvolvimento de Software |
| GPP | Gerência de Projeto e Portifólio de Software |
| IC | Integração Contínua |
| VM | Virtual Machine (máquina virtual) |
| AWS | Amazon Web Service |

### 2. Milestones

Os milestones serão os marcos dos pequenos entregáveis e releases reais do projeto.
| DATA | Descrição |
| 9/05/2015 | Configurar repositório para que o script do Travis execute a suite de testes, chame o serviço do coveralls e poste no Slack |
| 02/06/2015 | Atomatização da implantação utilizando o Chef |
| 16/06/2015 | Utilização do Fabric ou Chake para facilitar utilização do Chef |
| 27/06/2015 | Finalizar o fluxo de automação e integração |

### 3. Andamento

Andamento do desenvolvimento e alterações de escopo do projeto.

#### 3.1 Alterações de Escopo

Inicialmente, a integração contínua a ser empregada no projeto estava planejada para acontecer com a ajuda da ferramenta Travis, mas já que a integração contínua irá disparar a implantação automática usando o rake + chef (+ chake) para execução de comandos na máquina remota, diversas informações, como senhas ssh, iriam ficar visíveis no serviço aberto do travis. Para tornar isso fechado, decidimos mudar a ferramenta de integração contínua do Travis para o Jenkins, e levantá-lo em um servidor pessoal.
| Antes | Agora |
| Travis | Jenkins |
| Fabric ou Chake | Decisão pelo Chake |
| Serviço aberto inseguro | Instancia própria com mais segurança |

#### 3.2 Progresso

Progresso de tarefas do desenvolvimento de GSC no projeto.

##### 3.2.1 Feito

* Sincronização do repositório com o serviço do Travis
* Estudo a respeito do Chef e das dependências que ele precisa trazer
** Dependências para trazer na receita de configuração de ambiente de desenvolvimento
** Dependências para trazer na receita de configuração de ambiente de implantação
* Estudo a respeito do Fabric e Chake, e decisão pelo Fabric
** Decisão pela mudança de ferramenta de IC
* Utilização de uma VM na Amazon Web Service (trial de um ano grátis) para a instância do Jenkins
** Configuração do servidor nginx para o levantamento do Jenkins
** Configuração do Jenkins, seus plugins, geração de relatórios, e Jobs para IC do projeto
* Desenvolvimento da receita de configuração de ambiente de desenvolvimento (agora sendo a mesma que a de deploy, mas generalizada para funcionar local ou deploy)
* Adaptação do script do Jenkins para integração entre IC e ambiente de implantação com o Chake

### 4. Passo a passo da execução do projeto

Os temas abordados nesse projeto, como integração contínua, automatização de ambientes e de deploy, podem ser reproduzidos em diversos outros projetos, e de maneira geral, seguem passo a passo semelhante. Por esse motivo, a execução desse projeto será detalhada aqui.

#### 4.1 VMs em Web Service

Existem diversas opções de Web Services disponíveis, algumas pagas, e outras com período de trial. Utilizamos duas VMs de ubuntu 15 da azure (pagas) para implantar a aplicação. Também utilizamos uma VM ubuntu 14.04 (trial) para configuração do jenkins.

##### 4.1.1 Azure

O Microsoft Azure é um serviço pago, entretanto, um dos integrantes do Busine.me possui o plano BizSpark, onde o usuário tem direito à US$150,00 mensais para gastar com os serviços do Azure. Para criar uma VM no Azure:
* Acesse o dashboard do Azure e faça login na sua conta.
* Clique em "+ new" -> "Compute" -> "Virtual Machines" -> "From Gallery"
* Escolha uma das imagens disponíveis. Para o projeto, foi escolhido o Ubuntu Server 15.04.
* Defina o nome da sua VM, que será usado como DNS, sua configuração e o usuário padrão, bem como a forma de login, se por chave .pem ou senha. Para o projeto, foram definidas duas VMs:
** businemeweb.cloudapp.net: 1 core, 1.75 GB RAM. Login por senha.
** businemeapi.cloudapp.net: 1 core, 1.75 GB RAM. Login por senha.
* Defina as portas/saídas da VM. Para o projeto, em todas as VMs foram abertas as portas:
** 22 - SSH
** 80 - HTTP
* Finalize a criação da VM e aguarde até que o Azure termine de levantar a máquina.

##### 4.1.2 Amazon Web Service

Para criar uma VM na AWS, é necessário primeiro ter uma conta na amazon (mesma conta do site de compras).
* Com a conta criada, acesse https://aws.amazon.com/, faça login, e clique em MyAccount e em AWS management console.
* Depois siga para VMs EC2.
* Clique em launch Instance e então na distro desejada (Ubuntu 14.04).
* Siga as configurações, revendo os valores padrões. Nesse projeto só algumas portas sofreram port forward, mas não é necessário fazer isso nessemomento.
* Siga até o lanch, crie um novo keypair, nomei-o e faça o download do mesmo e guarde com cuidade o arquivo. Ele é utilizado para fazer ssh na máquina.
* Finalize o processo e então terá uma VM levantada pronta para acesso remoto.
* Para acessá-la via ssh, fique no diretório onde baixou o arquivo ".pem" e rode o comando utilizando nome do arquivo e ip da máquina:

#### 4.2 Levantar os Serviços

Nesse projeto diversas aplicações devem ser levantadas por trás de um nginx reverse proxy. Para o jenkins na maquina da AWS é necessário seguir as instruções desse link https://wiki.jenkins-ci.org/display/JENKINS/Running+Jenkins+behind+Nginx.
Para a aplicação em si rodando no servidor de homologação, ou no vagrant local, veja no tópico falando sobre a receita que configura isso.

#### 4.3 Como Aplicar IC

Após devidas configurações do supervisor e nginx do tópico anterior, é necessário iniciar o jenkins por trás dessa configuração e então configurá-lo. Para instalar o Jenkins:

##### 4.3.1 Plugins

Para instalar plugins no Jenkins basta navegar por "Manage Jenkins", "Manage Plugins" e selecionar a aba "Available". Os plugins necessários são:
* Cobertura
* Git client plugin
* Git parameter plugin
* Git plugin
* Git server plugin
* GitHub API plugin
* GitHub plugin
E assim que forem instalados, selecione opção de reiniciar o Jenkins para que estejam utilizáveis.

##### 4.3.2 Configuração Jenkins

* Estando na dashboard do Jenkins, Selecione "New Item".
* Nomeie o Job que irá rodar builds da aplicação.
* Coloque o link do projto no GitHub (https://github.com/aldarionsevero/BusinemeWeb/)
* Em Source Code Management, selecione git. Coloque a branch a ser monitorada, e suas credenciais.
* Escolha qual evnto irá dispará uma build do projeto (push).
* E por fim coloque os passos necessários anteriores para execução dos testes.
Nesse projeo são (pode-se separar em diversos blocos de "Execute Shell"):

#### 4.5 Vagrant

O Vagrant é a ferraemnta utilizada no projeto para gerenciamento de VMs para o ambiente de desenvolvimento. A criação e destruição de um abiente limpo e padronizado com o Vagrant garante integridade do ambiente, e é possível seguindo os seguintes passos:
* Primeiramente instale VirtualBox do seguinte link: https://www.virtualbox.org/wiki/Downloads (não instale via apt-get!!)
* Depois instale o Vagrant do seguinte link: https://www.vagrantup.com/download-archive/v1.7.1.html
* Estando no diretório desejado para o ambiente, rode o comando:
Esse comando cria o vagrant file que utilizaremos para configuração das VMS
* Não utilizaremos o chef como provisioner do Vagrant, como inicialmente planejado (tutorial para seguir com provisioner pode ser encontrado em outros projetos dessa turma), em vez disso utilizaremos o rake para acionar funcionalidades do chef por intermédio do chake. Dessa forma o nosso vagrant file fica assim:
Podemos observar que temos uma box limpa do ubuntu 14.04 (trusty64), que setamos um ambiente local e outro de deploy (BUSINEME_ENV), que fazemos as configurações de ip por meio de um arquivo yaml e que levantamos as VMS com essas configurações. Esses arquivos de configuração dependem do chake e serão melhor explicados no tópico apropriado.

#### 4.5 Integrar rake e chef com o chake

A parte mais trabalhosa do projeto vem dessa integração. Para isso é necessário primeiro instalar ruby, rake, chef e o chake:
Em seguida partimos para a configuração de tudo nos diretórios onde temos o Vagrantfile.

##### 4.5.1 Local (Vagrant)

Nesse diretório, executamos o seguinte comando:
que criará os seguintes arquivos:
* Antes de tudo iremos configurar o arquivo Rakefile, para que ao longo do tutorial possamos, além de levantar a VM, possamos rodar o rake.
Esse arquivo irá se utilizar de outros arquivos de configuração que iremos confecionar para que o rake possa passar valores que estarão nos arquivos dentro da pasta config, para as receitas e templates. Além disso seta nós e o script para gerar o bootstrap_common do ssh_config.
* Em seguida, após criar a estrutura de diretórios é deletar o diretório roles e criar dois diretórios novos: "local", "homologa", que são nossos ambientes de desenvolvimento e de deploy.
* Em cada um desses diretórios iremos criar os seguintes arquivos:
O mesmo pro outro diretório:
No arquivo config.yaml iremos colocar todos os paths de diretórios, URLs necessárias, nomes e versões. Principalmente as que sabemos que serão diferentes entre aplicação e api.
O arquivo ips.yaml segue mesmo padrão, mas colocaremos somente ips.
O arquivo ssh_config irá guardar as configurações de ssh e localização de chaves para as VMs.
Iremos configurar a parte local primeiro então os conteúdos desses arquivos ficam:
* Em seguida iremos configurar nossos nós (nessa aplicação: API e WEB). Fazemos isso no arquivo nodes.yaml. Aqui ja podemos chamar as receitas que posteriormente incluiremos nos diretórios de cookbooks (comente se quiser já levantar o vagrant com o comando vagrant up e uma VM limpa).
* O conteudo do config.rb pode ser mantido.
* Agora baixaremos as recipes/cookbooks externas que usaremos, e então faremos a nossa recipe interna do chef.
** Baixe as seguintes cookbooks no diretório cookbooks: git, apt, build-essential, chef-sugar, chef_handler, dmg, openssl, windows, yum, yum-epel. O site para o download é: https://supermarket.chef.io/
** No arquivo cookbooks/basics/recipes/default.rb, adicione o conteúdo:
Para dar um apt-get update e ter servidor ssh em suas VMs, antes de rodar outras receitas.
* Crie os seguintes diretórios agora:
No files/default irão os arquivos que, durante a configuração, deverão ser copiados sem alteração. No recipes criaremos nossas receitas. No templates default, colocaremos os arquivos que precisam de alguma generalização antes de serem copiados para algum diretório, durante a configuração feita pela receita.
Já que são muitos arquivos de configuração e templates, recomendamos consulta ao repositório:
https://github.com/Busineme/BusinemeChef/tree/master/cookbooks/busineme/files/default
https://github.com/Busineme/BusinemeChef/tree/master/cookbooks/busineme/templates/default
* Agora criaremos nossas receitas internas:
A receita da base de dados postgresql serve para a criação do usuário, criação do banco e inicialização do serviço. E tem o seguinte conteúdo:
* A receita web.rb é a que configurará a máquina que rodará a aplicação principal. Por partes temos:
Configuração de ambiente local e de deploy e instalações de dependências.
Modo debug para ambiente local e sem debug para ambiente de deploy.
Clone do repositorio usando a receita externa do git.
Instalaçã de requerimentos especificos da aplicação e configuração de ambiente da mesma por meio de templates.
Criação das tabelas no banco que ja foi criado pela receita do postgresql.
Configuração do supervisor para levantar o nginx como processo, script para levantar o gunicorn que faz o nginx entender o projeto Django como aplicação.
Resultado final:
* Com isso já é possível levantar o ambiente de desenvolvimento local. Basta seguir o diagrama de desenvolviemnto com os seguintes comandos:
Esses dois comandos podem demorar bastante pois levantam a VM sem nada e instalam tudo das receitas. A segunda vez irá só atualizar com mudanças (se houverem) nas receitas. Se for necessário destruir as VMs e todos seus vestígios, rode:
Para logar em alguma vm use:
ou
* Para visualizar o desenvolvimento, não é necessário rodar o runserver pra VM web, pois ele já está rodando pelo nginx. Basta acessar no ip 10.10.10.3 (arquivo de configuração de ips).
* Entretanto é necessário rodar o runserver da API

##### 4.5.2 Deploy

Para as configurações de deploy temos que ter conteúdo diferentes nos arquivos config.yaml, ips.yaml e ssh_config, agora no diretorio config/homologa. Esses conteúdos diferentes estão sendo passados para os templates e para as receitas, justamente para fazer com que sejam genéricos para rodarem locais ou em deploy.
Esses conteúdos serão:
* Também é necessário adicionar um post build action no Jenkins fazendo o seguinte:
Sendo que o repositório do BusinemeChef na máquina do jenkins já tem que estar clonado.
* Para rodar o chake para deploy:
* Para fazer um teste rápido talvez seja interessante rodar um
E digitar
Para verificar se o output é semelhante a esse:
Para ter certeza que tudo está em ordem antes de executar receitas.