Busine.me
1. Introdução
[editar | editar código-fonte]1.1 Visão Geral
[editar | editar código-fonte]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
[editar | editar código-fonte]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
[editar | editar código-fonte]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
[editar | editar código-fonte]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
[editar | editar código-fonte]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
[editar | editar código-fonte]Andamento do desenvolvimento e alterações de escopo do projeto.
3.1 Alterações de Escopo
[editar | editar código-fonte]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
[editar | editar código-fonte]Progresso de tarefas do desenvolvimento de GSC no projeto.
3.2.1 Feito
[editar | editar código-fonte]- 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
[editar | editar código-fonte]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
[editar | editar código-fonte]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
[editar | editar código-fonte]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[1] 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
[editar | editar código-fonte]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:
$ ssh -i nome_do_arquivo.pem ubuntu@XX.XX.XXX.XXX
4.2 Levantar os Serviços
[editar | editar código-fonte]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
[editar | editar código-fonte]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:
$ wget -q -O - https://jenkins-ci.org/debian/jenkins-ci.org.key | sudo apt-key add - $ sudo sh -c 'echo deb http://pkg.jenkins-ci.org/debian binary/ > /etc/apt/sources.list.d/jenkins.list' $ sudo apt-get update $ sudo apt-get install jenkins
4.3.1 Plugins
[editar | editar código-fonte]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
[editar | editar código-fonte]- 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"):
sudo apt-get install ruby chef python2.7 python-pip -y && \ sudo apt-get install libxml2 && \ sudo apt-get install libxslt1.1 && \ sudo apt-get install libxml2-dev && \ sudo apt-get install libxslt1-dev && \ sudo apt-get install python-libxml2 && \ sudo apt-get install python-libxslt1 && \ sudo apt-get install python-dev && \ sudo apt-get install python-lxml && \ sudo apt-get install python-setuptools && \ sudo pip install -r requirements.txt && \ sudo pip install python-Levenshtein && \ cp configuration/databases.py.template configuration/databases.py && \ cp configuration/security.py.template configuration/security.py && \ cp configuration/api.py.template configuration/api.py && \ rm models/migrations/0* && \ python manage.py makemigrations && \ python manage.py migrate && \ python manage.py jenkins && \ clonedigger --cpd-output -o ./reports/clonedigger.xml . && \ coverage run manage.py test && \
4.5 Vagrant
[editar | editar código-fonte]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:
$ vagrant init
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:
# -*- mode: ruby -*- # vi: set ft=ruby : require 'yaml' Vagrant.configure(2) do |config| config.vm.box = "ubuntu/trusty64" env = ENV.fetch('BUSINEME_ENV', 'local') if File.exist?("config/#{env}/ips.yaml") ips = YAML.load_file("config/#{env}/ips.yaml") else ips = nil end config.vm.define 'api' do |api| api.vm.network 'private_network', ip: ips['api'] if ips api.vm.network "forwarded_port", guest: 8080, host: 8079 end config.vm.define 'web' do |web| web.vm.network 'private_network', ip: ips['web'] if ips web.vm.network "forwarded_port", guest: 8000, host: 8001 end end
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
[editar | editar código-fonte]A parte mais trabalhosa do projeto vem dessa integração. Para isso é necessário primeiro instalar ruby, rake, chef e o chake:
$ sudo apt-get install ruby $ sudo gem install rake chef chake
Em seguida partimos para a configuração de tudo nos diretórios onde temos o Vagrantfile.
4.5.1 Local (Vagrant)
[editar | editar código-fonte]Nesse diretório, executamos o seguinte comando:
$ chake init
que criará os seguintes arquivos:
[create] nodes.yaml # que configurará os nós em que as receitas serão executadas [create] config.rb # que irá linkar os diretórios do chef para que o rake consiga puxar as funcionalidades [ mkdir] config/roles # iremos mudar para que configuremos nossos dois ambientes (local, BUSINEME_ENV) [ mkdir] cookbooks/basics/recipes/ # receita básica (geralmente executada em todos os nós) [create] cookbooks/basics/recipes/default.rb [create] Rakefile # Arquivo de configuração do rake para nós etc
- 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.
require 'yaml' $BUSINEME_ENV = ENV.fetch('BUSINEME_ENV','local') ips_file = "config/#{$BUSINEME_ENV}/ips.yaml" ssh_config_file = "config/#{$BUSINEME_ENV}/ssh_config" config_file = "config/#{$BUSINEME_ENV}/config.yaml" ENV['CHAKE_TMPDIR'] = "tmp/chake.#{$BUSINEME_ENV}" ENV['CHAKE_SSH_CONFIG'] = ssh_config_file require "chake" ips ||= YAML.load_file(ips_file) config ||= YAML.load_file(config_file) $nodes.each do |node| node.data['config'] = config node.data['peers'] = ips end file 'ssh_config.erb' if ['local'].include?($BUSINEME_ENV) file ssh_config_file => ['nodes.yaml', ips_file, 'ssh_config.erb', 'Rakefile'] do |t| require 'erb' template = ERB.new(File.read('ssh_config.erb')) File.open(t.name, 'w') do |f| f.write(template.result(binding)) end puts 'ERB %s' % t.name end end task :bootstrap_common => 'config/local/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:
$ cd config/local $ touch config.yaml $ touch ips.yaml $ ssh_config # Esse arquivo pode ser gerado pelo bootstrap_common do rake, mas também pode ser feito na mão (enquanto o bootstrap_não está genérico)
O mesmo pro outro diretório:
$ cd config/homologa $ touch config.yaml $ touch ips.yaml $ ssh_config
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:
# config.yaml (não copie esse comentario) DIRECTORIES: API_REPO: /vagrant/repo/busineme-api WEB_REPO: /vagrant/repo/busineme-web APPLICATION: WEB_REPOSITORY: https://github.com/Busineme/BusinemeWeb.git API_REPOSITORY: https://github.com/Busineme/BusinemeAPI.git API_URL: http://10.10.10.2:8080/api/v1/ SECRET_KEY: secret-key DATABASE: NAME: busineme USER: busineme PASSWORD: 1234 VERSION: 9.3
# ips.yaml (não copie esse comentário) api: 10.10.10.2 web: 10.10.10.3
# ssh_config (não copie esse comentário) Host * User vagrant UserKnownHostsFile /dev/null StrictHostKeyChecking no PasswordAuthentication no IdentitiesOnly yes LogLevel FATAL Host api Hostname 10.10.10.2 Port 22 IdentityFile .vagrant/machines/api/virtualbox/private_key Host web Hostname 10.10.10.3 Port 22 IdentityFile .vagrant/machines/web/virtualbox/private_key # vim: ft=sshconfig
- 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).
# dois nós chamando suas receitas api: run_list: - recipe[basics] # - recipe[busineme::postgresql] # comentado pois ainda iremos fazer essa receita # - recipe[busineme::api] web: run_list: - recipe[basics] # - recipe[busineme::postgresql] # - recipe[busineme::web]
- 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:
# default.rb execute "apt-get update" package 'openssh-server'
Para dar um apt-get update e ter servidor ssh em suas VMs, antes de rodar outras receitas.
- Crie os seguintes diretórios agora:
$ mkdir busineme/files/default busineme/recipes/ busineme/templates/default
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:
$ touch busineme/recipes/web.rb busineme/recipes/api.rb busineme/recipes/postgresql.rb
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:
#instala psql package "postgresql" # modo debug para ambiente local if ['local'].include?($BUSINEME_ENV) DEBUG = 'True' directory "#{REPODIR}" do recursive true end else DEBUG = 'False' end # arquivo configuracao template "/etc/postgresql/#{node['config']['DATABASE']['VERSION']}/main/pg_hba.conf" do source 'pg_hba.conf.erb' user 'postgres' group 'postgres' mode 0600 notifies :restart, 'service[postgresql]', :immediately end # criacao do usuario DB_USER = node['config']['DATABASE']['USER'] DB_PASSWORD = node['config']['DATABASE']['PASSWORD'] DB_NAME = node['config']['DATABASE']['NAME'] execute "createuser:#{DB_USER}" do command "psql -c \"CREATE USER #{DB_USER} WITH PASSWORD '#{DB_PASSWORD}';\"" user 'postgres' not_if "sudo -u postgres psql -c \"select * from pg_user where usename = '#{DB_USER}';\" | grep -c #{DB_USER}" end # criacao do banco execute "createdb:#{DB_NAME}" do command "createdb #{DB_NAME} --owner=#{DB_USER}" user 'postgres' not_if "sudo -u postgres psql -c \"select * from pg_database where datname = '#{DB_NAME}';\" | grep -c #{DB_NAME}" end service 'postgresql' do action [:enable, :start] supports :restart => true end
- 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.
# Variables $BUSINEME_ENV = ENV.fetch('BUSINEME_ENV', 'local') package "vim" package "python2.7" package "python-pip" package "python-dev" package "postgresql-contrib" package "libpq-dev" package "postgresql" package "git" package "libxml2" package "libxslt1.1" package "libxml2-dev" package "libxslt1-dev" package "python-libxml2" package "python-libxslt1" package "python-lxml" package "python-setuptools" package "python-Levenshtein" package "python-psycopg2" execute "pip install gunicorn" package "nginx" package "supervisor" package "nginx" include_recipe "git"
Modo debug para ambiente local e sem debug para ambiente de deploy.
REPODIR = node['config']['DIRECTORIES']['WEB_REPO'] if ['local'].include?($BUSINEME_ENV) DEBUG = 'True' directory "#{REPODIR}" do recursive true end else DEBUG = 'False' end
Clone do repositorio usando a receita externa do git.
git "#{REPODIR}" do repository node['config']['APPLICATION']['WEB_REPOSITORY'] action :sync end
Instalaçã de requerimentos especificos da aplicação e configuração de ambiente da mesma por meio de templates.
execute 'pip install -r requirements.txt' do cwd "#{REPODIR}" end template "#{REPODIR}/configuration/databases.py" do source "databases.py.erb" end template "#{REPODIR}/configuration/security.py" do source "security.py.erb" variables({:DEBUG => DEBUG}) end template "#{REPODIR}/configuration/api.py" do source "api.py.erb" end
Criação das tabelas no banco que ja foi criado pela receita do postgresql.
execute 'python manage.py makemigrations' do cwd "#{REPODIR}" end execute 'python manage.py migrate' do cwd "#{REPODIR}" end
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.
template "/etc/supervisor/conf.d/busineme.conf" do source "busineme.conf.erb" variables({:REPODIR => REPODIR}) mode 0600 end template "#{REPODIR}/gunicorn_script" do source "gunicorn_script.erb" variables({:REPODIR => REPODIR}) mode 0775 end service 'supervisor' do action :restart end execute 'supervisorctl start busineme' do cwd "#{REPODIR}" end file "/etc/nginx/sites-available/default" do action :delete end file "/etc/nginx/sites-enabled/default" do action :delete end template "/etc/nginx/sites-available/busineme.conf" do source "busineme-nginx.conf.erb" variables({:REPODIR => REPODIR}) mode 0600 end link "/etc/nginx/sites-enabled/busineme.conf" do to "/etc/nginx/sites-available/busineme.conf" notifies :restart, "service[nginx]" end service "nginx" do action [:enable, :start] supports :restart => true end
Resultado final:
# Variables $BUSINEME_ENV = ENV.fetch('BUSINEME_ENV', 'local') package "vim" package "python2.7" package "python-pip" package "python-dev" package "postgresql-contrib" package "libpq-dev" package "postgresql" package "git" package "libxml2" package "libxslt1.1" package "libxml2-dev" package "libxslt1-dev" package "python-libxml2" package "python-libxslt1" package "python-lxml" package "python-setuptools" package "python-Levenshtein" package "python-psycopg2" execute "pip install gunicorn" package "nginx" package "supervisor" package "nginx" include_recipe "git" REPODIR = node['config']['DIRECTORIES']['WEB_REPO'] if ['local'].include?($BUSINEME_ENV) DEBUG = 'True' directory "#{REPODIR}" do recursive true end else DEBUG = 'False' end git "#{REPODIR}" do repository node['config']['APPLICATION']['WEB_REPOSITORY'] action :sync end execute 'pip install -r requirements.txt' do cwd "#{REPODIR}" end template "#{REPODIR}/configuration/databases.py" do source "databases.py.erb" end template "#{REPODIR}/configuration/security.py" do source "security.py.erb" variables({:DEBUG => DEBUG}) end template "#{REPODIR}/configuration/api.py" do source "api.py.erb" end execute 'python manage.py makemigrations' do cwd "#{REPODIR}" end execute 'python manage.py migrate' do cwd "#{REPODIR}" end template "/etc/supervisor/conf.d/busineme.conf" do source "busineme.conf.erb" variables({:REPODIR => REPODIR}) mode 0600 end template "#{REPODIR}/gunicorn_script" do source "gunicorn_script.erb" variables({:REPODIR => REPODIR}) mode 0775 end service 'supervisor' do action :restart end execute 'supervisorctl start busineme' do cwd "#{REPODIR}" end file "/etc/nginx/sites-available/default" do action :delete end file "/etc/nginx/sites-enabled/default" do action :delete end template "/etc/nginx/sites-available/busineme.conf" do source "busineme-nginx.conf.erb" variables({:REPODIR => REPODIR}) mode 0600 end link "/etc/nginx/sites-enabled/busineme.conf" do to "/etc/nginx/sites-available/busineme.conf" notifies :restart, "service[nginx]" end service "nginx" do action [:enable, :start] supports :restart => true end
- Com isso já é possível levantar o ambiente de desenvolvimento local. Basta seguir o diagrama de desenvolviemnto com os seguintes comandos:
$ vagrant up $ rake # ou rake converge:web ou rake convege:api para rodar receitas específicas
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:
$ vagrant destroy
Para logar em alguma vm use:
$ rake login:web
ou
$ rake login:api
- 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
$ ./manage.py runserver 0.0.0.0:8080
4.5.2 Deploy
[editar | editar código-fonte]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:
# config.yaml (não copie esse comentário) DIRECTORIES: API_REPO: /opt/busineme-api WEB_REPO: /opt/busineme-web APPLICATION: WEB_REPOSITORY: https://github.com/Busineme/BusinemeWeb.git API_REPOSITORY: https://github.com/Busineme/BusinemeAPI.git API_URL: http://businemeweb.cloudapp.net/api/v1/ SECRET_KEY: secret-key DATABASE: NAME: busineme USER: busineme PASSWORD: 1234 VERSION: 9.4
# ips.yaml (não copie esse comentário) api: 23.96.43.247 web: 23.96.100.196
# ssh_config Host api Hostname 23.96.43.247 Port 22 User busineme Host web Hostname 23.96.100.196 Port 22 User busineme # vim: ft=sshconfig
- Também é necessário adicionar um post build action no Jenkins fazendo o seguinte:
git pull https://github.com/Busineme/BusinemeChef.git && \ cd BusinemeChef && \ sudo gem install rake && \ sudo gem install chake && \ rake BUSINEME_ENV=homologa
Sendo que o repositório do BusinemeChef na máquina do jenkins já tem que estar clonado.
- Para rodar o chake para deploy:
$ rake BUSINEME_ENV=homologa
- Para fazer um teste rápido talvez seja interessante rodar um
$ rake run BUSINEME_ENV=homologa
E digitar
$ date
Para verificar se o output é semelhante a esse:
api: $ date api: Thu Jul 2 04:41:18 UTC 2015 web: $ date web: Thu Jul 2 04:41:19 UTC 2015
Para ter certeza que tudo está em ordem antes de executar receitas.