O rsync é definitivamente a ferramenta certa para este trabalho. Existe para manter os diretórios sincronizados e pode fazê-lo com um pouco de inteligência. Por exemplo: ele transfere apenas deltas sempre que possível e pode trabalhar em túneis ssh.
Digamos que você tenha uma fonte de máquina que hospede sua versão ao vivo da árvore de diretórios /my/tree
e coletor de máquinas que deseja manter em estreita sincronização com ela. Se você tivesse uma conta ssh no coletor , poderia, a partir da fonte, usar o rsync da seguinte maneira:
rsync -avz --delete -e ssh /my/tree/ remoteuser@sink:/my/tree
Isso pressupõe que você deseja /my/tree
exatamente no mesmo local no coletor que o possui na fonte . Claro, você não precisa mantê-lo exatamente no mesmo local.
Quebrando a linha de comando:
-avz
: modo de arquivo morto, detalhado, use compactação durante a transferência
--delete
: excluir arquivos em sincronização que não estão presentes na origem
-e ssh
: Use ssh como o método de conexão
É claro que esta ligação solicitará sua senha quando você a fizer. Se você quiser fazer isso de alguma maneira automatizada, precisará compartilhar algumas chaves entre as contas nas máquinas e usar a criptografia de chave pública-privada para fazer a conexão ssh.
Para configurar seu par de chaves para este rysnc, execute o seguinte comando em sua máquina de origem :
> ssh-keygen -t rsa -b 2048 -f ~/.ssh/my-rsync-key
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase): [press enter here]
Enter same passphrase again: [press enter here]
Your identification has been saved in ~/.ssh/my-rsync-key.
Your public key has been saved in ~/.ssh/my-rsync-key.pub.
The key fingerprint is:
2e:28:d9:ec:85:21:e7:ff:73:df:2e:07:78:f0:d0:a0 root@source
> chmod 600 ~/.ssh/my-rsync-key
Para este par de chaves para o trabalho, precisamos adicionar o conteúdo de ~/.ssh/my-rsync-key.pub
ao ~<remoteuser>/.ssh/authorized_keys
arquivo na pia máquina.
Primeiro copie o arquivo para a máquina do coletor :
scp ~/.ssh/my-rsync-key.pub remoteuser@sink:~
Em seguida, faça o ssh na máquina do coletor e importe a chave executando o seguinte como usuário remoto na máquina:
> if [ ! -d ~/.ssh ]; then mkdir ~/.ssh ; chmod 700 ~/.ssh ; fi
cd ~/.ssh/
if [ ! -f authorized_keys ]; then touch authorized_keys ; chmod 600 authorized_keys ; fi
cat ~/my-rsync-key.pub >> authorized_keys
rm ~/my-rsync-key.pub
Para obter dicas adicionais sobre como bloquear a conexão ssh entre as máquinas de origem e de pia , recomendo dar uma olhada nesta página .
Na sua máquina de origem , você pode testar se essa configuração funciona executando:
rsync -avz --dry-run -e "ssh -i ~/.ssh/my-rsync-key" /my/tree/ remoteuser@sink:/my/tree
Isso fará uma execução seca de um rsync. Se você vir o comando rsync conectando e comparando os arquivos, sabe que as coisas estão configuradas corretamente.
Agora precisamos de uma maneira fácil de chamar esse comando rsync a partir de um arquivo de configuração do LaunchD, como mostrado nesta resposta útil neste site . Como você deseja que essa chamada aconteça em um loop restrito, será necessário garantir que você não tenha várias cópias do rsync em execução ao mesmo tempo. Você pode usar o flock para criar um mutex que garanta que um script bash seja único: apenas uma instância é executada a cada vez em uma máquina. Então, vamos criar o seguinte script em disco:
#!/bin/sh
SINK_INSTANCE=remoteuser@sink
DIR=/my/tree
KEY=~/.ssh/my-rsync-key
LOG = ~/my_rsync.log
LOCK = ~/my_rsync.lock
SOURCE=/my/tree
exec 9>${LOCK}
if ! flock -n 9 ; then
echo "Another instance of your rsync is already running";
exit 1
fi
echo "----------" >> ${LOG}
echo `date` >> ${LOG}
rsync -avz --delete -e "ssh -i ${KEY}" \
${SOURCE}/ {SINK_INSTANCE}:${SOURCE} 2>&1 >> ${LOG}
Salve isso como ~/my_rsync.sh
.
Esse script cuidará de fazer o rsync para você. Tudo o que você precisa fazer agora é configurá-lo via LaunchD e executá-lo em um circuito fechado. Seguindo as instruções a partir daqui e modificando-o para atender às nossas necessidades, vamos criar ~/Library/LaunchAgents/my-rsync.plist
em um editor de texto e criar o conteúdo:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>My Rsync</string>
<key>Program</key>
<string>/bin/sh</string>
<key>ProgramArguments</key>
<array>
<string>sh</string>
<string>-c</string>
<string>while sleep 5s; /Users/my/my_rsync.sh; done</string>
</array>
<key>ServiceDescription</key>
<string>Keep /my/tree synchronized with the machine sink</string>
<key>KeepAlive</key>
<true/>
</dict>
</plist>
Isso deve cuidar das coisas.
As advertências usuais se aplicam: escrevi isso de memória e não testei. Portanto, não siga cegamente. Teste com cuidado ao longo do caminho. Sempre que tiver dúvidas, use a --dry-run
opção no rsync. Ele imprimirá o que teria feito sem realmente fazer nada.