Um servidor SVN remoto

Dando continuidade ao artigo anterior eu mostro agora como configurar (de forma básica, porém funcional) de um servidor SVN remoto.

O SVN naquele artigo foi visto na máquina local, mas imagine que precisássemos dele em uma máquina remota sendo acessada a partir da rede por meia dúzia de desenvolvedores?

Tipos de repositório remoto

Para isso temos duas alternativas: o suporte a WebDAV do Apache, ou o svnserver. Existem vantagens e desvantagens em ambos os métodos e que não serão discutidas aqui (consulte o guia vermelho para sanar estas dúvidas).

A solução que apresento aqui é a com svnserver. Ao executar o comando svnserve com o parâmetro -d um processo daemon rodará em background escutando conexões na porta tcp/3690 (Anote isso caso você viva atrás de um firewall) e assim, ao invés de file://caminhodorepositorio você passa a usar svn://servidor/repositorio (exceto para os comandos do svnadmin).

Iniciando o repositório no boot

Na intenção de automatizar as coisas, eu criei um script muito simples e funcional, que inicia o svnserver de uma durante o processo de boot do meu sistema. Segue a listagem:

#!/bin/bash
##### svn_daemon.sh ########
#Inicia/para o servidor SVN

#Criado por Welington Braga - webcontato {AT} welrbraga.eti.br
#Originalmente publicado em 10-10-2007 e distribuido sob a licença GPL
#Fonte: https://blog.welrbraga.eti.br/?p=12

. /lib/lsb/init-functions

#Caminho dos repositorios
ROOT_REP="/srv/subversion"

#Pra que mexer daqui pra baixo se ja esta funcionando!?
NOME="Subversion"
SERVER=`type -p svnserve`
MODO="--daemon --threads"
USER="subversion"
GRUPO="subversion"
PIDFILE="/tmp/svnpid"
#Arquivos de log estão implementados apartir da versão 1.6 do Svn
#LOGFILE="$ROOT_REP/subversion.log"
#CMDLINE="$MODO --pid-file $PIDFILE --log-file $LOGFILE --root $ROOT_REP"
CMDLINE="$MODO --pid-file $PIDFILE --root $ROOT_REP"

if [ ! -x $SERVER ]; then
  echo "O servidor SVN parece nao estar instalado."
  exit 1
fi

if [ ! -d $ROOT_REP ]; then
  echo "  O caminho para o(s) repositorio(s) ($ROOT_REP) nao existia. Criando..."
  mkdir -p $ROOT_REP
  chown $USER:$GRUPO $ROOT_REP
  echo "  * Nao esqueca de criar algum repositorio com svnadmin create [caminho]"
  echo "    e definir as permissoes em conf/passwd conf/snvserver.conf e conf/authz"
fi

#if [ ! -f $LOGFILE ]; then
#  echo "Criando o arquivo de log ($LOGFILE)"
#  touch $LOGFILE
#  chown $USER:$GRUPO $LOGFILE
#fi

if [ "$1" == "start" ]; then
  echo "Iniciando $NOME..."
  start-stop-daemon --pidfile $PIDFILE --make-pidfile --umask 007 --background --exec $SERVER --start -- $CMDLINE
fi
if [ "$1" == "stop" ]; then
  echo "Parando $NOME..."
  start-stop-daemon --pidfile $PIDFILE --exec "$SERVER" --stop
fi
if [ "$1" == "restart" ]; then
  echo "Parando $NOME..."
  start-stop-daemon --pidfile $PIDFILE --exec "$SERVER" --stop
  rm $PIDFILE

  echo "Iniciando $NOME..."
  start-stop-daemon --pidfile $PIDFILE --make-pidfile --umask 007 --background --exec $SERVER --start -- $CMDLINE
fi
echo "Feito."
##### FIM svn_daemon.sh ######

Para simplificar mais ainda a vida eu usei as funções padrões da especificação lsb para iniciar o servidor – especificamente a ‘start-stop-daemon‘ – de maneira que este script poderá ser executado no boot de (teoricamente) qualquer distribuição Linux que suporte esta especificação (tal como Debian, Ubuntu e derivados). Note ainda os parâmetros ROOT_REP, USER e GROUP que podem/devem ser alterados de acordo com a sua necessidade.

Para que este script seja iniciado no boot você deverá salvá-lo no /etc/init.d e depois configurar com:

# update-rc.d svn_daemon.sh defaults

Iniciando o repositório manualmente

Na realidade você nem precisaria deste script caso queira rodar o servidor manualmente. Um simples …

$ svnserve -d -r caminho/onde/estarao/seus/repositorios

… pode ser a solução do seu problema, mas eu optei por fazer o script de maneira a ficar algo mais rebuscado podendo assim criar o caminho para os repositórios, ter um registro do que está acontecendo, permitir um start/stop elegante etc, em fim, mera perfumaria.

Uma vez que o servidor esteja no ar (simples assim) você precisa criar um repositório dentro dele (caso já não exista) e definir os usuários/permissões de acesso.

Criando o repositório

Agora que o seu servidor de repositórios esté no ar, você deverá criar o(s) repositório(s) e para isso, usa-se o comando svnamin create com o caminho completo para o novo repositório (como já mostrado anteriormente).

Lembre-se que os comandos do svnadmin (vide artigo anterior e a página de manual) rodam apenas localmente no servidor, portanto após levantar o servidor você deverá criar o repositório com o comando abaixo (não esqueça de logar antes com o usuário que inicia o svnserver), a partir de um terminal deste servidor:

$ svnadmin create /srv/subversion/SEUREPOSITORIO

Os arquivos de configuração do repositório

Tão logo se crie o repositório você precisa dar as permissões de acesso o que é feito em três arquivos dentro da pasta “conf” no seu repositório.

Arquivo ‘authz’

Este arquivo é o responsável pela autorização de acesso ao repositório e contém basicamente dois tipos de seções. A seção ‘group’ e a(s) seção(ões) com o caminho a dar permissão.

A seção [groups] define grupos de acesso. Ex:

[groups]
desevolvedores = huguinho,luizinho,zezinho
gerentes=donald,mickey

A seção com o nome dos diretórios é simplesmente definida como abaixo:

[/]
@desenvolvedores = rw
joao = rw
@gerentes = r
* =

Neste exemplo estamos definindo permissões a partir da raiz (/) do repositório em questão. Os usuários do grupo ‘desenvolvedores’ e o usuário ‘joao’ terão permissão de leitura/escrita (rw), os usuários do grupo ‘gerentes’ apenas terão acesso de leitura (r) enquanto que os demais usuários (anônimos, inclusive) não poderão acessar este repositório.

Arquivo ‘passwd’

Este arquivo possui apenas a seção [users] e com uma mais linhas definindo os usuários que poderão acessá-lo de seguinte forma:

[users]
huginho = h4560
luizinho = lz22dn
zezinho = nhozi
donald = margarida
mickey = key99

Observe que este arquivo contém o par usuário = senha de todos os seus usuários em modo plano (não criptografado), por isso não incentive o uso das mesmas senhas dos demais sistemas.

Arquivo ‘svnserver.conf’

O arquivo snvserver.conf define as permissões globais do repositório. Abaixo está o modelo genérico que já está por default em todos os repositórios que você criar, sem os comentários em inglês. Você pode seguramente colocar este conteúdo no lugar do seu, ou apenas descomentar estas linhas.

[general]
anon-access = none
auth-access = write
password-db = passwd
authz-db = authz
realm = Meu primeiro repositorio

Note que aqui definimos que por padrão usuários anônimos não terão acesso ao repositório (linha 2), enquanto os usuários que autenticarem poderão ler/gravar (linha 3); as linhas 3 e 4 definem os arquivos de permissões já comentados anteriormente e a última linha define o ‘reino’ do repositório. O reino não é apenas uma descrição ou comentário sobre o repositório, mas uma forma de agrupar vários repositórios, dando-lhes algum tipo de organização. No geral você pode simplesmente escrever o nome de sua empresa e pronto.

Ferramentas clientes

Uma vez feito isso seu repositório está pronto pra uso e todos os usuários definidos poderão autenticar e compartilhar seus códigos. E para fazer isso existem várias ferramentas. Particularmente eu gosto do RapidSVN que é uma interface cliente feita com GTK e que me supre bem as necessidades, mas existem interfaces baseadas na Qt para o ambiente KDE, como o KDEsvn, e até para Windows, como o TortoiseSVN. Em modo texto use os comandos svn, svnadmin diretamente da linha de comandos (vide artigo anterior).

A vantagem dos clientes visuais, para ambiente gráfico, é que você a partir de uma única interface poderá editar, comparar, enviar e receber os arquivos de qualquer repositório sem decorar qualquer comando em linha de comandos.

Existe ainda alguns editores comerciais como o Syncro SVN Client. Se quiserem testar depois me digam o resultado.

Algo mais?

É claro que existe muito mais sobre o SVN que eu não abordei. Se interessar, dêem uma lida nestes dois artigos:

Ambos os artigos tratam do SVN via Apache com WebDAV e em particular este segundo tem uma boa lista de comandos para modo texto. Vale a pena a leitura.

4 comentários em “Um servidor SVN remoto”

  1. Amigo, instalei o svn num servidor do laboratório em que trabalho, funcionou direitinho, meu único problema foi fazer o svn rodar no boot do servidor, segui os passos que você recomenda, mas mesmo assim não funcionou. Se puder me ajudar ficaria agradecido.

  2. @Thiago Campos
    Bom, eu não lembro se respondi a esta dúvida diretamente por e-mail ao Thiago, nem se acabei deixando passar desapercebido, mas como esta é uma dúvida que pode atingir outras pessoas então optei por responder ainda que tardiamente (Thiago, peço minhas sinceras desculpas se não o respondi antes, não foi por mal que fiz isso, ok?)

    Indo direto a questão, como eu já havia dito, o script para iniciar o repositório usa funções LSB para maior compatibilidade, mas isso não significa que todas as distros os suportem diretamente. Talvez você tenha que instalar um pacote a parte para isso (procure por pacote contendo LSB no seu nome).

    Outra sugestão também é você criar o seu próprio script sem muitas firulas onde apenas o comando:

    svnserve -d -r caminho/onde/estarao/seus/repositorios

    será executado.

    Também é importante lembrar que algumas distribuições lidam de maneira diferente com scripts de inicialização, então você pode até mesmo pegar um script pequeno que já exista em sua máquina e alterá-lo.

    Sem muito stresse você pode também criar o script em algum local como /usr/local/bin, ou mesmo em /opt e incluir uma linha o chamando no arquivo /etc/rc.local.

    PS: Este arquivo deve ter permissão de execução: chmod +rx /etc/init.d/svn_daemon.sh.

    Lembro ainda que este arquivo deve ser salvo em /etc/init.d e que o comando update-rc.d deve ser executado como root.

  3. Caro Welington, seu blog tem sido muito útil. Parabéns pelo trabalho!

    Bem, a instalação do SVN foi bem simples (Versão: 2.6.0 no Ruindows – IIS) e utilização do Tortoise é bem simples.

    Porém estou com um problema: manter os arquivos do meu sistema web atualizados – Pasta Inetpub/wwroot/sistema.

    Quando faço um commit, os arquvos vão para dentro do repositório e não para a pasta do sistema.

    Como atualizar a pasta Inetpub/wwroot/sistema imediatamente após um commit?

    Como “tirar” os arquivos que acabaram de chegar no repositório e “colocar” na pasta web?

    Mais uma vez, parabéns pelo blog e obrigado pela ajuda.

  4. Grande @Thiago,
    Você está fazendo falta na equipe, vou mandar buscá-lo de volta 😉

    Como você já constatou, o repositório do Subversion não é um diretório com a “réplica” do que foi enviado para lá. Ele possui diversas cópias e arquivos de controle que não podem e não devem ser publicados diretamente na web.

    Se você quer usar um serviço de versionamento para gerenciar seu servidor WEB você terá que trabalhar com publicação indireta. Assim, você faz um “commit” com suas modificações para o repositório e o próprio sistema do Subversion, através de um gancho de “pos-commit”, executa um “update” ou mesmo um “checkout” para a raiz do seu serviço WEB. Um script bem elaborado poderia usar a estrutura “acadêmica” do Subversion (trunk, branches e tags) para decidir se deve publicar os arquivos no servidor WEB de desenvolvimento ou de produção, embora isso não seja necessário.

    Eu fiz um script em “bash” para este fim que funcionou muito bem por algum tempo, mas como o versionamento deixou de ser usado por aqui, eu não não tenho mais o script no servidor. Vou procurá-los nos meus backups e achando-o vou dar um trato nele para publicar aqui. Mas o básico é o que eu descrevi acima. qualquer dúvida estamos ai.

    abç

Deixe um comentário para Thiago Luna Cancelar resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.