Auto-update e database migrations

241 views
Skip to first unread message

Camilo Carromeu

unread,
Feb 27, 2013, 12:20:53 PM2/27/13
to titan-f...@googlegroups.com
Olá pessoal,

Foi disponibilizado no Titan em UTF-8 um script de auto-update para as instâncias. Este script funciona delegando ao schedular job do sistema operacional a tarefa de manter a instância atualizada no servidor.

Ele é baseado no script de auto-update do SIGFAP, mas com melhorias significativas.

O script tira uma casquinha do conceito de database migrations implementado pelo Ruby on Rails (http://guias.rubyonrails.com.br/migrations.html), 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:

MyApp/
  configure/
  section/
  ...
  update/
    app/
      production.txt
      test.txt
      ...
    db/
      20130220123401.sql
      20130225021401.sql
      20130227234701.sql
      ...
    blacklist.txt

Os arquivos TXT dentro da pasta 'update/app' relatarão quais arquivos devem ser atualizados naquela revisão. São chamados de "arquivos de caminhos" ("file of paths"). O nome do arquivo define o ambiente em que a atualização será aplicada.

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 da criação desta estrutura você precisa inserir configurações adicionais no 'configure/titan.xml' da sua instância:

<titan-configuration ...>
    ...
    <update
        environment="test"
        svn-login="update"
        svn-password=""
        svn-users="camilo"
        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. É fundamental para que o script saiba qual file of paths deverá considerar. Os atributos 'svn-login' e 'svn-password' devem ser configurados com um usuário e senha do repositório SVN com o código da instância. O atributo 'svn-users' define quais usuários possuem commits que podem ser atualizados, ou seja, caso seja commitado um file of paths por um usuário não especificado nesta diretiva, ele será desconsiderado no momento do update. 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" (https://groups.google.com/d/topic/titan-framework/ZD0pSu-FKFQ/discussion). 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, quem e quando ela foi aplicada.

O script funciona da seguinte forma:

1. Primeiro ele captura a versão atual da work copy no servidor e a head revision do file of paths para o ambiente no repositório SVN;
2. Por meio de um laço ele atualiza o file of paths para a versão posterior (revisão atual + 1);
3. Para cada iteração do laço, ele atualiza a pasta 'update/db' para a mesma revisão e verifica qual a última versão do banco de dados (tabela "_version");
4. Em seguida, ele efetua backup do DB;
5. Então, ele aplica as alterações no DB. Caso ocorra erro, é realizado um rollback no DB e o file of paths é atualizado para a última revisão corretamente aplicada;
6. Em caso de sucesso os arquivos (paths) listados no file of paths são atualizados para a revisão da iteração;
7. Por fim, não havendo problemas esta revisão passa a ser a última revisão estável e o laço avança para a próxima iteração.

Desta forma, mesmo um sistema que esteja sendo instanciado no servidor a partir de um backup antigo teria 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).

Reparem também na existência do arquivo "update/backlist.php". Neste arquivo podem ser colocadas revisões que devem ser desconsideradas. Assim, o script sempre atualiza este arquivo para a head revision e consulta seu conteúdo, permitindo manipular as revisões que serão de fato aplicadas.

Para que o script funcione é necessário que esteja executando em um servidor *NIX, sendo que está homologado especificamente para Debian Squeeze. Será necessário também instalado no PHP a biblioteca SVN do PECL:

# aptitude update
# aptitude install build-essential php-pear php5-dev libsvn-dev
# pecl update-channels
# pecl install svn
# echo "extension=svn.so" > /etc/php5/conf.d/svn.ini
# /etc/init.d/apache2 restart

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 derá 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.

Espero que seja útil.

Abraços,

Camilo

P.S.: Um agradecimento especial ao Jairo Rodrigues e ao Bruno Righes que propuseram a implementação de database migrations.

Maxwell Sampaio

unread,
Sep 2, 2013, 4:44:56 PM9/2/13
to titan-f...@googlegroups.com
Pessoal,

Fiz a configuração de uma instância do TitanUTF8 para utilizar este script de auto-update, entretanto, após as configurações da instância (arquivo titan.xml abaixo) fui executar o comando para rodar o script e recebi a seguinte mensagem:

root@ip-10-152-152-194:/var/www/contafacil# php /var/www/titanutf8/core/update/update.php /var/www/contafacil/ > /var/www/log/titan-auto-update.log
svn: E175002: Unable to connect to a repository at URL 'https://svn.cnpgc.embrapa.br/titan/core/update'
svn: E175002: OPTIONS of 'https://svn.cnpgc.embrapa.br/titan/core/update': Server certificate verification failed: certificate has expired, certificate issued for a different hostname, issuer is not trusted (https://svn.cnpgc.embrapa.br)


Trecho arquivo titan.xml da instância:
        <backup
                path="backup_db/"
                validity="86400"
                timeout="86400"
        />

        <update>
                environment="production"
                svn-login="update"
                svn-password=""
                svn-users="maxwell,rodrigo_devigo,mais"
                backup="true"
                file-mode="770"
                dir-mode="770"
                owner="www-data"
                group="www-data"
        </update>

 
O que será que tem de errado que o servidor não está conseguindo executar o script de auto-update? Alguém já conseguiu executar este script em alguma nova instância do titan UTF8?



Atenciosamente,

Maxwell Sampaio
Mestre em Ciência da Computação pela FACOM/UFMS


2013/2/27 Camilo Carromeu <cam...@carromeu.com>

--
Você está recebendo esta mensagem porque se inscreveu no grupo "Titan Framework" dos Grupos do Google.
Para cancelar a inscrição neste grupo e parar de receber seus e-mails, envie um e-mail para titan-framewo...@googlegroups.com.
Para obter mais opções, acesse https://groups.google.com/groups/opt_out.
 
 

Maxwell Sampaio

unread,
Sep 2, 2013, 4:58:44 PM9/2/13
to titan-f...@googlegroups.com
Pessoal,

Já consegui resolver este problema, o que faltava era executar o comando SVN UP /var/www/titanutf8/ e salvar a senha de atualização do repo no servidor. Depois disto o script funcionou, entretanto, verificando no arquivo de log do script:

INFO > Starting auto-update proccess at 02-09-2013 16:53:52...
INFO > Updating Titan Framework...
INFO > Getting last stable revision...
INFO > Titan Framework is already updated!

INFO > Starting auto-update for instance [/var/www/contafacil]...
INFO > The file 'titan.xml' is loaded! [/var/www/contafacil/configure/titan.xml]
ERROR > You need set a environment name on tag 'update' of 'titan.xml'!

Está dando erro na tag update mas ela está definida corretamente, conforme mensagem anterior, o que será que está errado desta vez?
 

Atenciosamente,

Maxwell Sampaio
Mestre em Ciência da Computação pela FACOM/UFMS


2013/9/2 Maxwell Sampaio <maxs....@gmail.com>

Márcio Silva

unread,
Sep 2, 2013, 5:23:11 PM9/2/13
to titan-framework
Max, falta colocar o atributo environment="".
--

 
 
 
Márcio Silva
 

 
Campo Grande, MS - Brasil  |  Engenharia de Software

Email: map...@gmail.com
Blog: www.arenaacademica.com
Ledes: www.ledes.net
Olimpo Tecnologia: www.olimpotec.com
SIGFap: www.sigfap.net
Tel: +55 67 33457532



 


        

Maxwell Sampaio

unread,
Sep 2, 2013, 5:36:15 PM9/2/13
to titan-f...@googlegroups.com
Já consegui arrumar, o erro estava na definição da tag update:


Antes estava:
        <update>
                environment="production"
                svn-login="update"
                svn-password="#uP2d@7&$"
                svn-users="maxwell,rodrigo_devigo,mais"
                backup="true"
                file-mode="770"
                dir-mode="770"
                owner="www-data"
                group="www-data"
        <update/>


Agora está:

      <update
                environment="production"
                svn-login="update"
                svn-password="#uP2d@7&$"
                svn-users="maxwell,rodrigo_devigo,mais"
                backup="true"
                file-mode="770"
                dir-mode="770"
                owner="www-data"
                group="www-data"
        />

Já consegui rodar o script e recebi email com sucesso.

Vlw.


Atenciosamente,

Maxwell Sampaio
Mestre em Ciência da Computação pela FACOM/UFMS


2013/9/2 Márcio Silva <map...@gmail.com>

Camilo Carromeu

unread,
Sep 3, 2013, 9:05:12 AM9/3/13
to titan-f...@googlegroups.com
Opa Max,

É bom mudar essa senha, pois acho que você mandou sem querer pra lista toda.

Outra coisa, verifique se estas permissões são o que você quer mesmo. Se for um servidor Debian/Ubuntu talvez seja melhor remover os atributos file-mode e dir-mode para que o Titan coloque valores padrão, onde arquivos ficam com permissão de leitura e apenas diretórios recebem de execução (para listagem).

Abraços,

Camilo


2013/9/2 Maxwell Sampaio <maxs....@gmail.com>

Maxwell Sampaio

unread,
Sep 6, 2013, 4:52:45 PM9/6/13
to titan-f...@googlegroups.com
Pessoal,

No tutorial inicial altere:

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

para 

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



Altere também:

*/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]

para

*/5 * * * * root /usr/bin/php /var/www/[caminho para o Titan]/core/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]



No mais está OK, implantei em uma instância do Titan e está funcionando corretamente.


Atenciosamente,

Maxwell Sampaio
Mestre em Ciência da Computação pela FACOM/UFMS


2013/9/3 Camilo Carromeu <cam...@carromeu.com>

Maxwell Sampaio

unread,
Sep 6, 2013, 5:14:19 PM9/6/13
to titan-f...@googlegroups.com
Camilo,

Tentei atualizar arquivos que estão fora do diretório da instância commitei o arquivo production.txt com o seguinte conteúdo:

../../application/default/views/scripts/contact/index.phtml
../../application/default/views/scripts/index/footer.phtml
../../application/default/views/scripts/index/index.phtml
../../application/default/models/Picture.php

Mas o script gerou erro informando que não é possível atualizar.

Tem alguma forma de configurar o script para permitir atualização de arquivos que estão em diretórios acima da instância do Titan?



Atenciosamente,

Maxwell Sampaio
Mestre em Ciência da Computação pela FACOM/UFMS


2013/9/6 Maxwell Sampaio <maxs....@gmail.com>

Camilo Carromeu

unread,
Sep 6, 2013, 10:30:38 PM9/6/13
to titan-f...@googlegroups.com
Olá Max,

Em relação ao seu primeiro e-mail, somente o CORE do Titan é necessário que esteja na workcopy do framework nos servidores de homologação e produção, ou seja, '/var/www/titan' seria uma checkout de 'https://svn.cnpgc.embrapa.br/titan/core' (e não da raiz do repositório), por conta disso a referência direta. Mas, claro, vai da preferência do usuário. 

Por segurança o Titan não permite que sejam atualizados arquivos fora da pasta real da instância e da pasta real do Titan. Não adianta nem mesmo utilizar links simbólicos. O script de auto update roda como root, por conta disso é suscetível a abrir brechas de segurança no servidor. Por exemplo, caso não houvesse esta restrição de segurança, em um servidor como o production eu poderia atualizar outro sistema simplesmente passando no 'production.txt' um caminho do tipo '../outro_sistema'.

Você poderia fazer uma gambiarra aí... mas fica por sua conta e risco. A ideia seria criar uma pasta 'update' e o arquivo 'configure/titan.xml' na raiz deste sistema. Aí passaria o caminho para ele como se fosse uma instância do Titan. Por exemplo, no crontab você teria algo do tipo:

*/5 * * * * root /usr/bin/php /var/www/titan/core/update/update.php /var/www/sua_aplicacao/ /var/www/sua_aplicacao/public/manager/ > [arquivo com log de saída]

Abraços,

Camilo


2013/9/6 Maxwell Sampaio <maxs....@gmail.com>

Camilo Carromeu

unread,
Sep 10, 2014, 1:25:17 PM9/10/14
to titan-f...@googlegroups.com

Pessoal,

Alguns devem ter percebido que a versão do Titan agora fica exposta no rodapé das instâncias:


Este evidenciamento é um esforço para tornar o controle de versões mais explícito no uso do framework. Pensando nisso, naquelas instâncias que utilizam o auto-deploy, há agora um controle melhorado da versão da instância.

Toda vez que um é feito um deploy  de uma release pelo sistema automático, é gerado um arquivo na pasta de cache com dados do release publicado ("cache/RELEASE"). Uma vez disponíveis, estas informações são também evidenciadas no rodapé da aplicação:

Inline image 1

A versão da instância pode ser informada ao Titan no arquivo "update/VERSION". No caso do PLEASE Lab, as versões de aplicações têm o formado "V.YY.MM-RRRR", onde o 'V' é o número da versão-macro da aplicação, o "YY.MM" é o número da sprint e "RRR" é o número do release. Por exemplo, na figura acima a versão da aplicação que estava sendo executada no momento do print screen era a "2.14.12-620".

A primeira parte deste número, ou seja, a versão-macro da aplicação e o sprint, são manualmente declarados no arquivo "update/VERSION". Este arquivo é automaticamente atualizado pelo sistema de auto-deploy. A segunda parte, ou seja, o release, é o número da versão no SVN e é obtido automaticamente pelo Titan. Portanto este último será sempre incremental.

Abraços,

Camilo

Camilo Carromeu

unread,
Sep 3, 2015, 1:10:54 PM9/3/15
to Titan Framework
Olá pessoal,

Uma pequena alteração no sistema de auto-update. Agora os e-mails com o log da atualização acompanham o changelog da instância e do Titan. :

INSTANCE CHANGELOG
======== =========

Revision #463 of 02-09-2013 13:37:21 (-04:00 GMT) by camilo.carromeu
Diversas correções e refatorações relacionadas à tarefa. Em relação ao "Público Alvo", ao invés da alterações nos dados foi criada uma nova seção de gestão.

Revision #466 of 02-09-2013 15:51:58 (-04:00 GMT) by camilo.carromeu
Criação da figura "Gestor" em tecnologias, um grupo de pessoas que pode editar a tecnologia até que ela seja bloqueada.

Revision #470 of 02-09-2013 16:27:30 (-04:00 GMT) by camilo.carromeu
Alteração, a tempo, para que o Módulo de Tecnologias utilize um componente próprio (e não 'custom engines') possibilitando mudanças mais radicais na estrutura.

TITAN CHANGELOG
===== =========

Revision 462 of 07-07-2015 11:28:28 (-04:00 GMT) by camilo.carromeu
Pequena alteração no método GET do tipo nativo 'Note' para retornar o CODE das notas.

Revision 464 of 15-07-2015 15:32:21 (-04:00 GMT) by camilo.carromeu
Alteração nas chamadas da dunção 'apache_setenv' para correção de bug quando rodando em servidores NGINX.

Revision 466 of 12-08-2015 15:00:30 (-04:00 GMT) by camilo.carromeu
Correção no layout da página de cadastro/recadastro de senha.

Revision 468 of 18-08-2015 09:58:30 (-04:00 GMT) by camilo.carromeu
Pequena alteração na altura dos campos de formulários abertos via Ajax.
Adicionado ao e-mail do sistema de auto-deploy a informação sobre a URL da instância.

Reparem que o Titan monta o changelog com base nas mensagens inseridas nos commits do SVN. Ou seja, ele lista todas as revisões criadas entre a versão atual em produção para àquela que o sistema está sendo atualizado. 

É possível ampliar os detalhes de cada modificação ou suprimir completamente esta informação dos e-mails por meio do atributo 'changelog' que pode ser colocado na tag 'update' do arquivo 'titan.xml'. Este atributo aceita três valores:
  • 'none': remove completamente os changelogs dos e-mails;
  • 'default': é o valor padrão e adicionará aos e-mails o changelog apenas com as mensagens dos commits, conforme o exemplo acima (caso a mensagem seja vazia, a revisão não é mostrada); e
  • 'full': adiciona também quais arquivos foram modificados.
Abraços,

Camilo
Reply all
Reply to author
Forward
0 new messages