Deployment no symfony 1.4 – Corrigido
Quem tentou trabalhar com o deployment do symfony – leia symfony 1.4 -, provavelmente já teve problemas. Este artigo, trata de uma particularidade sobre o sistema de deploy do symfony 1.4 em ambiente Windows, que tem uma solução simples e eficaz.
Eu tentei encontrar alguns tópicos relacionados a este assunto mas não encontrei nada. Acredito que isto seja porque poucos tem a possibilidade de usar contas com acesso shell em seus servidores de hospedagem – isto, portanto, faz com que poucos desenvolvedores usem o rsync.
Nem sempre um shared hosting dá a possibilidade do uso de uma conta shell, o que é compreensivel. Bom, se você não tem uma conta shell, passe a ter, e se usa um shared host passe a usar um VPS ou um servidor dedicado. Já tive sérios problema quanto a usar um shared host, mas isto explicarei em outro momento.
Este problema passou a ocorrer quando migrei do symfony 1.2 para o 1.4. É interessante notar que o modo de executar comandos shell no symfony 1.4 mudou. No 1.2 temos o uso do passthru() enquanto no 1.4 temos o proc_open() – um executa um comando shell e retorna sua saída crua e o outro executa um comando (abre um processo) e abre ponteiros de entrada e saída.
O problema na realidade, não está no symfony, mas sim na função proc_open() do php, mais especificamente nos pipes criados pelo PHP na execução do comando rsync – ou qualquer outro comando que venha a ser. Isto acontece somente em determinados momentos onde o stream STDERR é preenchido e faz com que o stream STDOUT congele e gere um loop infinito no Windows – obrigado ao Luceo.
Eu confesso que este problema, não foi tão simples de se resolver, já que se trata de um problema bem especifico do PHP e do Windows. Contudo proponho aqui duas soluções para o problema.
A primeira, e mais correta é alterar o modo de acesso do pipe STDERR na classe sfFilesystem.class.php, linha 291:
$descriptorspec = array(
1 => array('pipe', 'w'), // stdout
2 => array('pipe', 'a'), // stderr
);
Isto faz com que o ponteiro do stream STDERR saia da posição inicial – w mode – e vá para a posição final – a mode. Ou seja, basta mudar o modo de acesso do pipe que o problema se resolve.
A segunda solução é tão simples quanto a apresentada. Basta customizar os parametros inseridos pelo symfony no comando rsync, ou seja, simplesmente omita o parametro –progress. Veja o exemplo abaixo:
[production]
host=smartlinks.com.br
port="22 -i E:/cygwin/home/Augusto/.ssh/id_rsa"
user=smartlinks
dir=/home/smartlinks/website
parameters="-azC --force --delete --exclude-from=config/rsync_exclude.txt"
Lembrando novamente: Este problema acontece somente a partir da versão 1.3 do symfony onde foi mudado a maneira como é executado comandos shell pelo symfony. Anteriormente usava-se o passthru() e agora o proc_open().
Cheguei a abrir um ticket sobre este problema no website do bugtrac do symfony mas até o momento não obtive nenhuma resposta sobre o problema. Assim que tiver alguma posição aviso vocês.
Não cheguei a olhar este assunto no symfony 2.0 mas assim que tiver tempo darei um olhada.
Espero ter ajudado.