Este script de auto-update para instâncias do Titan objetiva manter instâncias atualizadas em ambientes remotos de teste, homologação e/ou produção a partir da consulta sistemática ao repositório GIT onde está versionado seu código. Caso sua instância utilize um repositório de código SVN, por favor, acesse as instruções para ativação do script de auto-deploy para instâncias em repositórios SVN. Este script funciona delegando ao schedular job do sistema operacional a tarefa de manter a instância atualizada no servidor.

O script é baseado no conceito de database migrations implementado pelo Ruby on Rails, que nada mais é que a gestão e rastreabilidade de mudanças incrementais no banco de dados da aplicação.

Para que o script de auto-update funcione corretamente é necessário criar na raiz da instância a seguinte estrutura de diretórios (caso não exista):

MyApp/
  configure/
  section/
  ...
  update/
    db/
      20130220123401.sql
      20130225021401.sql
      20130227234701.sql
      ...

Na pasta ‘update/db’ ficam as alterações a serem aplicadas no banco de dados. As alterações devem sempre ser colocadas no formato ‘YYYYMMDDHHUUNN.sql’, onde: ‘YYYY’ é o ano, ‘MM’ é o mês, ‘DD’ é o dia, ‘HH’ é a hora, ‘UU’ é o minuto e ‘NN’ é um número sequencial iniciado em 01 (para cada minuto). Estes valores são referentes ao momento em que o arquivo é criado. O nome do arquivo é a versão do banco de dados.

Além disso, a sua work copy do projeto deve estar clonada com uso de uma SSH Key cadastrada no repositório. Nesta modalidade, o GIT não solicitará login e senha para atualizar o código da work copy (pull). Veja como cadastrar a SSH Key no GitHub e no GitLab.

Além da criação desta estrutura você precisa inserir configurações adicionais no ‘configure/titan.xml’ da sua instância:

1
2
3
4
5
6
7
8
9
10
11
<titan-configuration ...>
    ...
    <update
        environment="test"
        backup="true"
        file-mode="664"
        dir-mode="775"
        owner="root"
        group="staff"
    />
</titan-configuration>

O atributo ‘environment’ diz qual é o ambiente em que a instância está executando. Deve existir no seu repositório GIT uma branch homônima. O sistema de auto-deploy irá “vigiar” esta branch buscando novas tags, ou seja, para informa o script que uma nova versão deve ser disponibilizada no ambiente, basta criar uma nova tag nesta branch. Deve-se, portanto, controlar quem pode publicar código no ambiente por meio das permissões de commit e merge da branch. Por exemplo, todos os desenvolvedores podem commitar código para a branchmaster’ e fazer merge da ‘master’ na ‘test’, mas somente os gerentes de projeto podem fazer merge da ‘test’ na ‘production’.

Recomenda-se fortemente que os nomes das tags criadas nas branches sigam o padrão Semantic Versioning 2.0.0. Mais especificamente, cada tag é nomeada no formato V.YY.MM-pPP, onde:

  • V é a versão-macro em desenvolvimento da aplicação;
  • YY.MM é o milestone, representado por ano e mês (com dois dígitos cada) da data prevista (due date); e
  • PP é o build, ou seja, um valor incremental iniciando em ‘1’ ou vazio dentro de um mesmo milestone.

Na figura baixo podem ser observados os três branches principais (perenes) do repositório GIT de uma instância do Titan que utiliza o script de auto-deploy. Os branchestest’ e ‘production’ permitem o deploy automatizado do código nos ambientes de teste e produção, respectivamente. Para isso, foram criadas tags toda vez que era necessário efetuar a atualização. Por exemplo, a tag ‘2.16.12-p39’ corresponde ao build ‘39’ do milestone ‘16.12’ da macro-versão ‘2’ desta aplicação.

Seguindo este padrão de nomes, o Titan irá disponibilizar na interface da instância o acesso ao número completo da versão da aplicação, atualizando esta informação toda ves que a work copy passar pelo processo de auto-deploy.

É importante que a sua work copy seja, portanto, um clone da branch declarada na configuração. Você pode utilizar o script de instalação da instância (deploy) para facilitar a publicação da aplicação Web de forma adequada ao auto-deploy.

O atributo ‘backup’ diz se deverá ou não ser realizado o backup do banco de dados antes que sejam aplicadas alterações. Repare que o backup apenas será efetuado se houverem alterações a serem aplicadas no DB. Atenção! Caso não seja explicitamente setado o valor “false” nesta diretiva, o script de auto-update sempre tentará fazer o backup, ou seja, o valor padrão deste atributo é “true”. A pasta de backup será a mesma utilizada pela funcionalidade backup on demand. Após a validade setada nesta funcionalidade os arquivos de backup do auto-update serão automaticamente apagados, preservando o espaço fisíco do servidor.

As demais configurações (‘file-mode’, ‘dir-mode’, ‘owner’ e ‘group’) devem ser setadas apenas caso a instância não esteja em um ambiente Debian. Referem-se às permissões que os arquivos atualizados receberão.

A primeira vez que o script é executado ele cria automaticamente uma tabela “**version**” no _schema do Titan no banco de dados. Esta tabela irá controlar as versões do BD, o autor da modificação e quando ela foi aplicada.

O script funciona da seguinte forma:

  1. Primeiro ele captura a versão (tag) atual da work copy no ambiente local e a tag mais recente na branch no repositório remoto (origin);
  2. Havendo diferença entre as versões, o script atualiza o código da work copy para a versão (tag) mais recente;
  3. Em seguida, verifica qual a última versão do banco de dados (tabela “_version”) e verifica se existem arquivos do database migrations a serem aplicados;
  4. Caso exista, ele efetua backup do DB;
  5. Então, ele aplica as alterações no DB. Caso ocorra erro, é realizado um rollback no DB e a work copy é revertida para a versão (tag) original.

Desta forma, mesmo um sistema que esteja sendo instanciado no servidor a partir de um backup antigo terá todas as revisões metodicamente aplicadas recursivamente.

Vale lembrar que, indepentende da quantidade de iterações do laço que possuam alterações a serem aplicadas no DB, o script irá gerar, por execução, apenas um backup inicial (e somente se houver alterações a serem aplicadas).

Para que o script funcione é necessário que esteja executando em um servidor *NIX, sendo que está homologado especificamente para Debian Jessie.

Para executar o script basta chamá-lo passando como parâmetro todas as instâncias que deseja atualizar (sem limite de instâncias). O script em si (que deverá ser chamado) está localizado na pasta ‘update’ do core do Titan. Por exemplo:

php /var/www/titan/update/update.php /var/www/portal/gestor/ /var/www/sigadhoc/ /var/www/fundect/manager/

No exemplo acima o script irá atualizar em sequência as três instâncias passadas. Lembrando que cada uma delas deverá ter a pasta ‘update’ (como a estrutura de pastas descrita) e deverá ter a tag ‘<update />’ em seu ‘configure/titan.xml’.

Conhecendo o funcionamento do script basta agora inserí-lo no schedular job do sistema operacional. No caso do Linux edite o arquivo “/etc/crontab” inserindo a linha abaixo:

*/5 * * * * root /usr/bin/php /var/www/[caminho para o Titan]/update/update.php /var/www/[caminho para a primeira instância] /var/www/[caminho para a segunda instância] > [arquivo com log de saída]

Neste caso o script irá executar a cada 5 minutos. Altere o número ‘5’ para aumentar o período de tempo.

Por exemplo:

*/20 * * * * root /usr/bin/php /var/www/titan/update/update.php /var/www/portal/gestor/ /var/www/sigadhoc/ /var/www/fundect/manager/ > /var/log/titan-auto-update.log

Ou seja, na configuração acima as três instâncias do nosso exemplo inicial serão atualizadas a cada 20 minutos e o LOG será jogado no arquivo “/var/log/titan-auto-update.log”. Lembre-se de reiniciar o CRON após editar o ‘/etc/crontab’:

/etc/init.d/cron restart

Quando de fato a instância é atualizada, ao invés de jogar no LOG as informações da atualização (apenas da instância específica) são enviadas para o(s) e-mail(s) cadastrado(s) na diretiva ‘e-mail’ da tag ‘<titan-configuration />’ do arquivo ‘configure/titan.xml’ da instância e para os e-mails de todos os usuários que estejam associados a grupos com perfil de administrador.