sync2test - sincroniza arquivos do subversion

Publicado por Perfil removido (última atualização em 10/02/2010)

[ Hits: 8.725 ]

Download sync2test




O presente script sincroniza arquivos do servidor subversion com o servidor de testes.

Utiliza:

- svn
- rsync
- sed
- dialog

  



Esconder código-fonte

#!/bin/bash
# sync2test
# Programa de sincronizacao de codigo-fonte com o servidor de teste
# 10/10/2009 - Luiz Sanches - luizgrsanches@gmail.com
# Versao 0.18

principal() {
   # Definicao de variaveis do programa
   SCRIPT="sync2test"
   VERSAO_SCRIPT=$(sed '/Versao/!d; q' $0)

   DIR_SCRIPT=$(pwd)

   DIR_CONF="/opt/$SCRIPT"
   DIR_CONF_USER="$HOME/.$SCRIPT"

   ARQUIVO_CONF="$DIR_CONF/$SCRIPT.conf"
   ARQUIVO_CONF_USER="$DIR_CONF_USER/$SCRIPT.conf"

   ARQUIVO_PROJETOS="$DIR_CONF/projetos"

   # Criacao dos diretorios de configuracao do programa
   [ ! -e "$DIR_CONF" ] && mkdir "$DIR_CONF"
   [ ! -e "$DIR_CONF_USER" ] && mkdir "$DIR_CONF_USER"

   # Definicao do program de dialogo como o usuario
   if [ "$DISPLAY" ]; then
      DIALOG="Xdialog"

      # Verifica a existencia do programa Xdialog
      [ ! -e "/usr/bin/$DIALOG" ] && DIALOG="dialog"
   else
      DIALOG="dialog"
   fi

   # Verifica a existencia dos programas
   verificaArquivo "/usr/bin/$DIALOG"
   verificaArquivo "/usr/bin/svn"
   verificaArquivo "/usr/bin/rsync"
   verificaArquivo "/bin/sed"

   # Cria a variavel $DIALOG_TITLE com parametro do titulo na tela de fundo
   DIALOG="$DIALOG --backtitle '$SCRIPT - Sincroniza SVN com Servidor de Teste. ${VERSAO_SCRIPT:2} - Usuario: $USER '"

   # Verifica a existencia do arquivo de projetos
   if [ ! -e "$ARQUIVO_PROJETOS" ]; then
      echo "siig:Sistemas Integrados" > $ARQUIVO_PROJETOS
   fi

   # seleciona os projetos, no arquivo projetos, com o padrao projeto:descricao
   LISTA_PROJETOS=$(sed '-n' 'p' $ARQUIVO_PROJETOS | sed 's/:/ "/;s/$/"/')

   while : ; do   
      # Selecao de projeto
      PROJETO=$(eval "$DIALOG --stdout --menu \"Selecione o projeto:\" 0 0 0 $LISTA_PROJETOS")

      # Se cancelar, sai do programa
      [ $? -ne 0 ] && break

      # Verifica a existencia do arquivo de modulos das gerencias
      if [ "$PROJETO" = "siig" ]; then
         ARQUIVO_MODULOS="$DIR_CONF/${PROJETO}_modulos"

         if [ ! -e "$ARQUIVO_MODULOS" ]; then
            echo "gpi:Afr:Administracao de Frota" > $ARQUIVO_MODULOS
            echo "gpi:Sco:Controle de Obras" >> $ARQUIVO_MODULOS
            echo "gpi:Gestao:Sala de Gestao" >> $ARQUIVO_MODULOS
            echo "gpa:Seg:Seguranca" >> $ARQUIVO_MODULOS
            echo "gpa:Cpr:Controle de Processos" >> $ARQUIVO_MODULOS
            echo "gpa:Aof:Administracao Financeira" >> $ARQUIVO_MODULOS
            echo "gpa:Talentos:Banco de Talentos" >> $ARQUIVO_MODULOS
         fi
      fi

      # Verifica a existencia do arquivo de configuracao, para carregamento das variaveis
      if [ -e "$ARQUIVO_CONF" ]; then
         . $ARQUIVO_CONF
      else
         SERVIDOR=$(eval $DIALOG --stdout --inputbox \"Digite o endereco do servidor SVN:\" 0 0 \"ip\")
         DIR_REPOSITORIO=$(eval $DIALOG --stdout --inputbox \"Digite o caminho do repositorio SVN \(com / no final\):\" 0 0 \"/var/svn/\")
         DIR_DESTINO=$(eval $DIALOG --stdout --inputbox \"Digite o diretorio de destino \(com / no final\):\" 0 0 \"/var/www/\")
         USUARIO_SVN=$(eval $DIALOG --stdout --inputbox \"Digite o nome do usuario de acesso ao SVN:\" 0 0 \"$USER\")
         SENHA_SVN=$(eval $DIALOG --stdout --inputbox \"Digite a senha do usuario SVN:\" 0 0 \"senha\")

         echo "SERVIDOR=\"$SERVIDOR\"" > $ARQUIVO_CONF
         echo "DIR_REPOSITORIO=\"$DIR_REPOSITORIO\"" >> $ARQUIVO_CONF
         echo "DIR_DESTINO=\"$DIR_DESTINO\"" >> $ARQUIVO_CONF
         echo "USUARIO_SVN=\"$USUARIO_SVN\"" >> $ARQUIVO_CONF
         echo "SENHA_SVN=\"$SENHA_SVN\"" >> $ARQUIVO_CONF
      fi

      # Verifica a existencia do arquivo de configuracao do usuario, para carregamento das variaveis
      if [ -e "$ARQUIVO_CONF_USER" ]; then
         . $ARQUIVO_CONF_USER
      else
         # Selecao de gerencia
         GERENCIA=$(eval $DIALOG --stdout --menu \"Selecione a gerencia em que trabalha:\" 0 0 0 GPI \"Projetos_Institucionais\" GPA \"Projetos_Academicos\")

         # Converte o conteudo da variavel gerencia para minusculo
         GERENCIA=$(echo $GERENCIA | tr [:upper:] [:lower:])

         # se a gerencia for nula, emitir mensagem e retornar a tela de projetos
         if [ -z "$GERENCIA" ]; then
            eval $DIALOG --title \"$SCRIPT\" --msgbox \"Nenhuma gerencia foi selecionada.\" 0 0
            continue
         fi

         echo "GERENCIA=\"$GERENCIA\"" > $ARQUIVO_CONF_USER
      fi

      # Arquivos de log
      ARQUIVO_LOG="$DIR_CONF_USER/.$SCRIPT-temp.log"
      DIR_LOG_PERMANENTE="$DIR_DESTINO/.$SCRIPT/log"
      ARQUIVO_LOG_PERMANENTE="$DIR_LOG_PERMANENTE/${PROJETO}_${USER}.log"

      [ ! -e "$DIR_LOG_PERMANENTE" ] && mkdir -p $DIR_LOG_PERMANENTE

      # Prepara o diretorio de sincronizacao
      DIR_TMP_SYNC="$DIR_DESTINO/.$SCRIPT/$PROJETO"

      [ ! -e "$DIR_TMP_SYNC" ] && mkdir -p $DIR_TMP_SYNC

      # Seleciona os modulos do projeto, no arquivo $PROJETO_modulos, com o padrao gerencia:modulo:descricao
      ARQUIVO_MODULOS="$DIR_CONF/${PROJETO}_modulos"
      
      verificaArquivo "$ARQUIVO_MODULOS"

      MODULOS_PROJETO=$(sed "/$GERENCIA/!d" $ARQUIVO_MODULOS | cut -d: -f2,3 | sed 's/:/ "/;s/$/"/')

      ARQUIVO_PROJETO_DEMAIS="$DIR_CONF/${PROJETO}_demais"

      ARQUIVO_PROJETO_COMPLETO="$DIR_CONF/${PROJETO}_completo"

      if [ "$PROJETO" = "siig" ]; then
         if [ ! -e "$ARQUIVO_PROJETO_DEMAIS" ]; then
            echo "/config/ d" > $ARQUIVO_PROJETO_DEMAIS
            echo "/controller/ d" >> $ARQUIVO_PROJETO_DEMAIS 
            echo "/model/ d" >> $ARQUIVO_PROJETO_DEMAIS 
            echo "/model/dao/ d" >> $ARQUIVO_PROJETO_DEMAIS 
            echo "/model/database/ d" >> $ARQUIVO_PROJETO_DEMAIS 
            echo "/model/generic/ d" >> $ARQUIVO_PROJETO_DEMAIS 
            echo "/model/template/ dr" >> $ARQUIVO_PROJETO_DEMAIS 
            echo "/model/utils/ dr" >> $ARQUIVO_PROJETO_DEMAIS 
            echo "/model/vo/ dr" >> $ARQUIVO_PROJETO_DEMAIS 
            echo "/view/ d" >> $ARQUIVO_PROJETO_DEMAIS 
            echo "/view/css/ dr" >> $ARQUIVO_PROJETO_DEMAIS 
            echo "/view/images/ dr" >> $ARQUIVO_PROJETO_DEMAIS 
            echo "/view/js/ dr" >> $ARQUIVO_PROJETO_DEMAIS 
            echo "/view/style/ dr" >> $ARQUIVO_PROJETO_DEMAIS 
         fi
      fi

      if [ -e "$ARQUIVO_PROJETO_DEMAIS" ] || [ -e "$ARQUIVO_PROJETO_COMPLETO" ]; then
         MODULOS_PROJETO="${MODULOS_PROJETO} Outros \"Outros diretorios\""
      fi

      while : ; do
         # deleta o arquivo de log para mostrar somente a ultima sincronizacao
         [ -e "$ARQUIVO_LOG" ] && rm $ARQUIVO_LOG

         # Selecao de modulo
         MODULO=$(eval $DIALOG --stdout --menu \"Selecione o modulo do projeto [$PROJETO] a ser atualizado para o servidor de teste:\" 0 0 0 $MODULOS_PROJETO)

         # Se cancelou retorna a tela de projetos
         [ $? -ne 0 ] && break

         # se escolher a opcao 'Outros'
         if [ "$MODULO" = "Outros" ]; then
            LISTA_OUTRAS_OPCOES=$(sed '-n' 'p' $ARQUIVO_PROJETO_COMPLETO | cut -d: -f1,2 | sed 's/:/ "/;s/$/"/')

            if [ -e "$ARQUIVO_PROJETO_DEMAIS" ]; then
               LISTA_OUTRAS_OPCOES="Demais \"Demais pastas do projeto [$PROJETO]\" ${LISTA_OUTRAS_OPCOES}" 
            fi

            while : ; do
               # deleta o arquivo de log para mostrar somente a ultima sincronizacao
               [ -e "$ARQUIVO_LOG" ] && rm $ARQUIVO_LOG

               # Selecao de outras opcoes
               OPCAO=$(eval $DIALOG --stdout --menu \"Selecione uma opcao:\" 0 0 0 $LISTA_OUTRAS_OPCOES)

               # Se cancelar retorna a tela de modulos
               [ $? -ne 0 ] && break

               eval $DIALOG --yesno \"Confirma a operacao?\" 0 0
            
               # Se escolher nao, retorna a tela de opcoes
               [ $? -ne 0 ] && continue

               if [ "$OPCAO" = "Demais" ]; then
                  # Executa a funcao para baixar o projeto do SVN
                  baixaProjetoSvn

                  while read LINHA
                  do
                     sincronizaDiretorio $LINHA
                  done < $ARQUIVO_PROJETO_DEMAIS

                  exibeResultado
               # Outros diretorios
               else
                  DIR_DESTINO_ESCAPE=$(echo $DIR_DESTINO | sed "s,\/,\\\/,g")

                  DIR_ALVO=$(sed "/$OPCAO/!d" $ARQUIVO_PROJETO_COMPLETO | cut -d: -f4)

                  # formata os caminhos de origem e destino, exemplo:
                  # antes.: siig:siig_homologacao
                  # depois: /var/www/siig/ /var/www/siig_homologacao/
                  PROJETO_COMPLETO=$(sed "/$OPCAO/!d" $ARQUIVO_PROJETO_COMPLETO | cut -d: -f3,4 | sed "s/^/$DIR_DESTINO_ESCAPE/; s/:/\/ $DIR_DESTINO_ESCAPE/; s/$/\//")

                  PROJETO_COMPLETO_SELECIONADO=$(sed "/$OPCAO/!d" $ARQUIVO_PROJETO_COMPLETO | cut -d: -f4)

                  DATA_HORA=$(date +%Y-%m-%d-%H-%M)

                  DIR_BACKUP="${DIR_DESTINO}bkp-${DIR_ALVO}/$DATA_HORA"

                  ARQUIVO_LOG_PERMANENTE="$DIR_LOG_PERMANENTE/${PROJETO_COMPLETO_SELECIONADO}_${USER}.log"

                  sincroniza $PROJETO_COMPLETO r

                  exibeResultado
               fi
            done
         else # Para a escolha de um modulo
            # Adiciona um nivel de diretorio na variavel modulo
            ARVORE="/view/"
            FACADE="$MODULO"

            # Converte o conteudo da variavel modulo para minusculo
            MODULO=$(echo $MODULO | tr [:upper:] [:lower:])

            DATA_HORA=$(date +%Y-%m-%d-%H-%M)

            DIR_BACKUP="${DIR_DESTINO}bkp-$PROJETO$ARVORE$MODULO/$DATA_HORA"

            # Une view/nome do modulo
            MODULO="$ARVORE$MODULO"

            # Executa a funcao para baixar o projeto do SVN
            baixaProjetoSvn

            # Sincroniza o projeto criando um backup
            # Se o diretorio do projeto nao existir, sincroniza tudo
            if [ ! -e "$DIR_DESTINO$PROJETO" ]; then
               sincroniza $DIR_TMP_SYNC $DIR_DESTINO a
            # Se existir, sincroniza somente os diretorios do modulo selecionado
            else
               sincroniza "$DIR_TMP_SYNC$MODULO" "$DIR_DESTINO$PROJETO$ARVORE" r "SIMULA"

               # Sincroniza as fachadas do modulo
               DIR_BACKUP="${DIR_DESTINO}bkp-$PROJETO/model/facade/$DATA_HORA"

               # Prepara o arquivo para nao sincronizar as outras fachadas
               ARQUIVO_EXCLUDE_MODULOS="$DIR_CONF_USER/.modulos"
               EXCLUDE_FACADE="$DIR_CONF_USER/.exclude_facade"

               [ -e "$ARQUIVO_EXCLUDE_MODULOS" ] && rm "$ARQUIVO_EXCLUDE_MODULOS"

               while read LINHA
               do
                  MOD=$(echo $LINHA | cut -d: -f2)
                  echo "$MOD*" >> $ARQUIVO_EXCLUDE_MODULOS
               done < $ARQUIVO_MODULOS

               sed "/^$FACADE/d" $ARQUIVO_EXCLUDE_MODULOS > $EXCLUDE_FACADE

               sincroniza "$DIR_TMP_SYNC/model/facade/" "$DIR_DESTINO$PROJETO/model/facade/" r --exclude-from=$EXCLUDE_FACADE
            fi

            exibeResultado
         fi
      done
   done

   clear
   exit
}

baixaProjetoSvn() {
   # Se o diretorio existir executar SVN update
   if [ -e "$DIR_TMP_SYNC" ]; then
      svn update $DIR_TMP_SYNC
   else # Senao, executar SVN checkout
      mkdir -p $DIR_TMP_SYNC
      svn checkout "svn://$SERVIDOR$DIR_REPOSITORIO$PROJETO" --username $USUARIO_SVN --password $SENHA_SVN $DIR_TMP_SYNC
   fi
}

sincroniza() {
   #echo $1 = origem
   #echo $2 = destino
   #echo $3 = r (recursive), a (archive), d (directory)
   #echo $4 = qualquer parametro do rsync

   # Seleciona arquivos que nao serao sincronizados
   ARQUIVO_PROJETO_EXCLUDE="$DIR_CONF/${PROJETO}_exclude"
   LISTA_EXCLUDE="$DIR_CONF_USER/.lista_exclude"
   LISTA_TMP="$DIR_CONF_USER/.lista_tmp"

   # Cria a lista de arquivos que nao seram sincronizados
   [ -e "$LISTA_EXCLUDE" ] && rm $LISTA_EXCLUDE

   [ -e "$ARQUIVO_PROJETO_EXCLUDE" ] && cat $ARQUIVO_PROJETO_EXCLUDE > $LISTA_EXCLUDE

   if [ "$4" = "SIMULA" ]; then
      # Simula (-n) a sincronizacao guardando em arquivo
      rsync -CvzpOu$3 -n --delete --exclude-from=$LISTA_EXCLUDE $1 $2 > $LISTA_TMP

      # Apaga as demais linhas, deixando somente os nomes dos arquivos
      sed '/^$/ d; /^sen/ d; /^total/ d; /^deleting/ d;' "$LISTA_TMP" > "${LISTA_TMP}1"
      sed "s/$/ '' OFF/g" "${LISTA_TMP}1" > "$LISTA_TMP"
      rm "${LISTA_TMP}1" 

      # Mostra os arquivos e opcao para selecionar os que nao seram sincronizados
      ARQ_EXCLUDES=$(cat $LISTA_TMP)

      [ -e "$LISTA_TMP" ] && rm $LISTA_TMP

      if [ -n "$ARQ_EXCLUDES" ]; then
         NAO_SINC=$(eval $DIALOG --stdout --separate-output --title \"Selecao de arquivos\" --checklist \"Selecione os arquivos que nao seram sincronizados\" 0 0 0 $ARQ_EXCLUDES)

         # Se nao cancelou
         if [ $? -eq 0 ]; then
            # Adiciona na lista os arquivos que nao seram sincronizados
            echo "$NAO_SINC" | while read LINHA
            do
               echo "$LINHA" >> $LISTA_EXCLUDE
            done

            # Sincroniza o projeto sem os arquivos selecionados anteriormente
            rsync -CvzpOu$3 --delete --no-perms -h -b --backup-dir=$DIR_BACKUP --log-file=$ARQUIVO_LOG --exclude-from=$LISTA_EXCLUDE $1 $2
         fi
      else
         # Sincroniza o projeto prevendo delecao de arquivos
         rsync -CvzpOu$3 --delete --no-perms -h -b --backup-dir=$DIR_BACKUP --log-file=$ARQUIVO_LOG --exclude-from=$LISTA_EXCLUDE $1 $2
      fi
   else
      # Sincroniza o projeto sem perguntar nada
      rsync -CvzpOu$3 $4 --delete --no-perms -h -b --backup-dir=$DIR_BACKUP --log-file=$ARQUIVO_LOG --exclude-from=$LISTA_EXCLUDE $1 $2
   fi

   if [ -e "$ARQUIVO_LOG" ]; then
      # Apaga as linhas abaixo do log para mostrar somente o nome dos arquivos sincronizados
      cp $ARQUIVO_LOG "$ARQUIVO_LOG.old"
      sed "/building/ d; /done/ d; /receiving/ d; /sent/,+1 d" "$ARQUIVO_LOG.old" > $ARQUIVO_LOG
      rm "$ARQUIVO_LOG.old"

      # Atualiza o arquivo de log permanente
      cat $ARQUIVO_LOG >> $ARQUIVO_LOG_PERMANENTE
   fi
}

sincronizaDiretorio() {
   #echo $1 = diretorio
   #echo $2 = opcao do rsync
   DATA_HORA=$(date +%Y-%m-%d-%H-%M)
   DIR_BACKUP="${DIR_DESTINO}bkp-$PROJETO$1$DATA_HORA"

   [ -e "$DIR_TMP_SYNC$1" ] && sincroniza "$DIR_TMP_SYNC$1" "$DIR_DESTINO$PROJETO$1" $2
}

exibeResultado() {
   CONTEUDO=$(cat $ARQUIVO_LOG)

   if [ -z "$CONTEUDO" ]; then
      eval $DIALOG --title \"log da atualizacao\" --msgbox \"Nenhum arquivo foi atualizado\" 0 0
   else
      eval $DIALOG --title \"log da atualizacao\" --textbox $ARQUIVO_LOG 0 0
   fi
}

verificaArquivo() {
   # Verifica a existencia do programa $1
   if [ ! -e "$1" ]; then
      echo "ATENCAO! O arquivo '$1' nao foi encontrado. Operacao cancelada."
      exit
   fi
}

principal

Scripts recomendados

Firewall do mikrotik, limitando icmp (ping)

mailnow - Envia mensagens pelo shell

Script para Firewall de Borda Corporativo

Automação para midias removíveis

Atualização do FreeBSD


  

Comentários
[1] Comentário enviado por parrera em 08/02/2010 - 15:24h

Olá estava precisando de um script para sincronizar o meu repositório com um espelho(remoto), sabe aonde posso encontrar?

[2] Comentário enviado por removido em 08/02/2010 - 16:17h

Olá Parrera, atualizei o script para a versão 1.04 que agora trabalha com sincronização do rsync via ssh. Ajudou bastante aqui no trabalho para transferir código do servidor de teste para o produção. Um detalhe para funcionar "redondo", é que temos que criar as permissoes do ssh para nao pedir senha ao conectar com o servidor de produção. Segue o trecho do script abaixo:

# Criar autorizacao para nao pedir senha ao conectar via ssh
if [ ! -e "$HOME/.ssh/authorized_keys" ]; then
ssh -p $PORTA_SSH "$USUARIO@$SERVIDOR" "mkdir ~/.ssh ; touch ~/.ssh/authorized_keys"
ssh-keygen -t dsa -f ~/.ssh/id_dsa
cat ~/.ssh/id_dsa.pub | ssh -p $PORTA_SSH "$USUARIO@$SERVIDOR" "cat - >> ~/.ssh/authorized_keys"
cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys
fi

Mas qualquer coisa, manda um mail, que te ajudarei na medida do possível


Contribuir com comentário