Sincronização automática de código via SSH para Unix

VN:RO [1.9.11_1134]
terça-feira, 22 d janeiro d 2013
Por Eduardo Russo, Coop10. Siga no Twitter

Trabalhando num projeto pessoal, ainda em fase bem beta, acabei caindo numa situação meio complicada.

O servidor onde estou rodando o projeto (Linux) tem uma configuração um tanto quanto diferente do meu Mac. Com isso, algumas coisas que rodam aqui não rodam lá e vice e versa.

Como não tenho saco para compilar uma versão similar do PHP na unha pra sobre escrever o que vem no Mountain Lion, nem de ficar editando o httpd.conf pra deixar as permissões de acesso corretas, muito menos pra achar uma VM e reinstalar um LAMP similar, acabei optando por testar as coisas diretamente no servidor.

Os CyberDuck, programa de FTP que tenho utilizado é bem espertinho e, com um duplo clique no arquivo remoto, o mesmo já abre no TextMate 2. Quando salvo no TM2, ele automaticamente vai para o servidor.

Tudo ótimo, tirando o fato de que tudo que altero remotamente precisa ser baixado para minha máquina, manualmente, para que eu tenha cópias locais e faça o versionamento via SVN.

Além disso, como o produto está tomando proporções maiores, nem sempre usar o TextMate 2 é a melhor opção, principalmente no momento em que começo a cogitar o uso de frameworks para desenvolver. Então, parti pro NetBeans, que, por si só, já faz sincronização automática via FTP, mas, caso eu edite uma linha de código fora dele, isso já falha.

Começa a busca…

Dessa forma, fui atrás de uma solução grátis que fizesse exatamente o seguinte:

  1. Identificar que um arquivo foi alterado
  2. Subir APENAS o arquivo alterado para o servidor remoto
  3. Me avisar que o processo está concluído e eu já posso apertar CMD+R (o F5 do Mac)

Encontrei várias menções ao “WinSCP“, cliente de FTP que promete fazer isso, mas, como o nome já diz, ele é exclusivo para Windows.

Depois, lí que o “Transmit“, cliente de FTP pra Mac também fazia. Baixei um trial, e descobri que ele falhava no quesito 1, não identificando alteração dos arquivos.

Aí, descobri que existe um comando no terminal chamado “rsync“, que faz o 2, mas nem sonha com o 1.

Vários foruns e StackOverflows depois, vi gente sugerindo loop infinito de rsync como “solução” para a sincronização em tempo real. Como bom nerd, me recuso a achar que loop infinito executando de 5 em 5 segundos é “tempo real”!

Enfim, depois de um fim de semana pesquisando, consegui montar um “set” de programas para fazer exatamente o que eu queria e, até o momento, tudo está funcionando exatamente como eu queria!

A solução “mágica”, porém complexa

Vamos lá, amiguinhos… primeiro, os “ingredientes” para nossa mágica:

  • SSH Passwordless Login – essa solução só funciona se você conseguir se logar via SSH sem o uso de senha. Nem todo servidor aceita isso!
  • rsync – acho que vem por padrão no Shell de todo Unix
  • HomeBrew – primo Macintóshico do aptitude de Linux
  • Watchdog – utilitário em Python que verifica se um arquivo foi alterado
  • Terminal Notifier – utilitário em Ruby que manda uma mensagem para o Notification Service do Mac. Não sei se existe algo similar para Linux
  • Criação de dois Shell Script para serem facilmente executados

Agora, ao passo a passo…

SSH Passwordless Login

Para conseguir fazer o login sem uso de senha via ssh, digite os seguintes passos no Terminal:

ssh-keygen -t rsa

Digite enter três vezes para aceitar os valores padrão. Isso irá criar uma chave de acesso da sua máquina.

Acesse seu servidor via FTP e crie uma pasta chamada .ssh (atenção com o ponto). Dentro dela, crie uma pasta chamada authorized_keys.

Copie a chave que foi criada para dentro da pasta authorized_keys.

Dessa forma, terá a seguinte estrutura na raiz do seu usuário FTP:

/.ssh/authorized_keys/id_rsa.pub

Agora, precisamos alterar as permissões desse arquivo. Dá pra fazer isso pelo programa de FTP ou via ssh + comando chmod.

A pasta .ssh deve ter permissões 700, isto é, dono do arquivo pode ler, escrever e executar.

A pasta authorized_keys deve ter permissão 600, isto é, o dono do arquivo pode ler e escrever, mas não executar.

Feito isso, experimente logar no seu servidor via ssh, pelo terminal:

ssh seu_usuario_de_ftp@seu_servidor.com

Verifique que não deve ser pedida senha… você simplesmente acessa, pois o servidor já tem uma autorização para seu computador (se fizer isso de outro local, a senha será pedida).

rsync

Se você conseguiu acessar o servidor sem usar senha, provavelmente todo o resto irá funcionar corretamente.

Para começar, vamos testar o rsync, para garantir que estamos sincronizando as pastas corretas e excluindo os arquivos corretos dessa sincronização (.svn, .git, .log etc.).

Para o teste, crie uma nova pasta no seu servidor, assim evitamos destruir seu site :P

Crie também uma pasta vazia no seu computador e digite o seguinte no Terminal:

rsync -azP --delete --exclude .svn --exclude .git --exclude .DS_Store --exclude .cvs --exclude '/cache' --exclude '/logs' ~/pasta_vazia_a_ser_sincronizada/ seu_usuario_de_ftp@seu_servidor.com:pasta_vazia_que_voce_criou_no_servidor/
  • -azP – não lembro o que significam, mas acho que tem a ver com subir apenas o que foi modificado
  • –delete – o que você deletar na sua máquina também será excluído do servidor
  • –exclude – tudo que você não quer que seja sincronizado
  • ~/pasta_vazia_a_ser_sincronizada/ – o caminho para a pasta do seu computador
  • seu_usuario_de_ftp@seu_servidor.com:pasta_vazia_que_voce_criou_no_servidor/ – conexão SSH com seu servidor. Depois dos “dois pontos”, é o caminho da pasta que será sincronizada

Coloque um arquivo de texto na sua pasta vazia e execute o comando… observe a mágica.

Agora, edite algo nesse texto, e execute o comando novamente.

Se tudo deu certo, depois de executar o comando, o arquivo é enviado ao servidor!

HomeBrew

Provavelmente o mais chatinho de instalar, já que precisa do GCC para ser compilado e, normalmente, se consegue o GCC instalando o IMENSO X-Code.

Mas, depois de instalar o IMENSO (não canso de repetir) X-Code, basta digitar o seguinte no Terminal.

ruby -e “$(curl -fsS http://gist.github.com/raw/323731/install_homebrew.rb)”
brew update

Watchdog

Com o HomeBrew devidamente instalado e atualizado, vamos adicionar uma dependência do Watchdog. Digite no Terminal:

brew install libyaml

Agora, vamos baixar o Watchdog. Basta digitar no Terminal:

sudo easy_install watchdog

Não vamos testá-lo agora, mas só depois, com a criação de um Shell Script.

Terminal Notifier

Finalmente, o não necessário, mas bastante importante notificador.

Como é um script Ruby, basta digitar o seguinte:

sudo gem install terminal-notifier

Após a instalação (bem rápida), teste se ele está funcionando:

terminal-notifier -message "Starting sync"

Se a janelinha de notificação do Mac apareceu, é porque funcionou!

Mensagem de Sincronização

Shell Script de verificação de atualização

Primeiro, vamos criar um Shell Script que sera nosso verificador.

Crie um novo arquivo de texto e digite o seguinte nele:

watchmedo shell-command \
	--patterns="*.php;*.js;*.css" \
	--recursive \
	--command='~/endereco_do_outro_script/FolderSync.sh' \
	.

Preste atenção nos espaços, na barra invertida e no ponto no final!

  • –patterns – define que tipo de arquivo que observar mudanças
  • –recursive – além da pasta inicial, olha todas as subpastas
  • –command – define o que você quer executar quando uma mudança for observada. Aqui, iremos executar o outro Shell Script, que executa o rsync e envia os alertas pro Mac.

Salve esse arquivo com a extensão “.sh”. Vamos chamá-lo de “FolderWatch.sh”.

Shell Script de sincronização e alerta

Crie um outro arquivo de texto com o seguinte:

#!/bin/bash
# Synchronization script
terminal-notifier -message "Starting Site sync"
rsync -azP --delete --exclude .svn --exclude .git --exclude .DS_Store --exclude .cvs --exclude '/cache' --exclude '/logs' ~/pasta_local_do_site_a_ser_sincronizado/ seu_usuario_de_ftp@seu_servidor.com:pasta_do_seu_site
terminal-notifier -message "Sync has finished"

Salve esse arquivo no caminho que você definiu no outro arquivo, o “FolderWatch.sh”

Agora, pelo terminal, vá até a pasta que deve ser sincronizada e execute o “FolderWatch.sh”.

~/caminho_do_folder_watch/FolderWatch.sh

Na minha máquina, sempre dá um alerta quando executo isso, mas aparentemente, nenhum problema acontece:

/Library/Python/2.7/site-packages/argh-0.22.0-py2.7.egg/argh/completion.py:84: UserWarning: Bash completion not available. Install argcomplete.

Agora, edite um arquivo do seu site e veja a mágica ocorrendo!

Imediatamente aparece a mensagem do Mac e, no terminal, a mensagem “* Notification delivered.”. Depois disso, o rsync executa e tudo que você alterou é enviado ao servidor.

Criando links dos Shell Scripts

Apenas para facilitar um pouco a vida, você pode criar links dos Shell Scripts para a pasta /usr/bin, de forma que eles sejam acessados sem precisarmos digitar o endereço completo deles:

ln -s ~/caminho_do_folder_watch/FolderWatch.sh /usr/bin
ln -s ~/caminho_do_folder_sync/FolderSync.sh /usr/bin

Finalmentes…

Deu um trabalho do cão descobrir tudo isso, mas realmente facilitou minha vida e agora eu durmo tranquilo sabendo que meu computador e meu servidor estão realmente espelhados!

Eu postei essa solução originalmente no StackOverflow, aqui e aqui :P

Se gostou, dá um up lá!

VN:F [1.9.11_1134]
Rating: 5.0/5 (1 vote cast)
Sincronização automática de código via SSH para Unix, 5.0 out of 5 based on 1 rating
Related Posts with Thumbnails

Eduardo Russo
Eduardo Russo

Formado em Engenharia de Computação pela Poli (2010) e em Design pela Belas Artes (2001), cofundador do Bit a Bit, fundador do Tubelivery e do Faviconit, cofundador da Fábrica de Aplicativos e coordenador de produto do Scup.

Tags: , , , , , , , , , , , , , , , , , ,

Um Comentário para “Sincronização automática de código via SSH para Unix”

  1. Diogo Dourado

    Parabens Eduardo, você acaba de ganhar o selo MacGyver!

    VA:F [1.9.11_1134]
    Rating: 0 (from 0 votes)
    #1172

Deixe um Comentário

Spam Protection by WP-SpamFree

Get Adobe Flash playerPlugin by wpburn.com wordpress themes