Use git para vários arquivos de configuração do servidor

14

Nós migramos muito código-fonte para o git e estamos muito felizes com a nossa solução atual. Gostaríamos de ter nossos arquivos de configuração de servidor com versão no mesmo sistema, mas há algumas coisas que não funcionam da maneira que gostaríamos e espero que alguém possa compartilhar sua experiência aqui.

Esta pergunta é semelhante a Usando o controle de revisão para arquivos de configuração do servidor? , mas temos alguns requisitos especiais que não funcionam com as sugestões dessa pergunta.

A configuração atual usa o subversion para arquivos de configuração. O repositório correspondente se parece com isso

 / # raiz do repositório
 + - www.domain.com/ # configuração para www
 | \ - etc /
 | \ - apache2 /
 + - dev.domain.com/ # configuração para dev
 | + - etc /
 | \--optar/
 | \ - app1 /         
 | \ - configuração conf / # para app1 no dev
 \ - staging.domain.com/ # configuração para teste

Com o subversion, isso funcionaria perfeitamente, porque é possível fazer o checkout de um subdiretório de um repositório. Além disso, você pode usar svn: externals para apontar para uma estrutura comum para várias configurações diferentes. Nós apenas tivemos que lidar com os arquivos .svn em todos os diretórios com versão. O Git, por outro lado , não possui svn: externals e checkouts esparsos sempre exigem que o caminho da raiz para o diretório real seja o mesmo.

Ao discutir a migração para o git, tentei anotar os principais requisitos para o versionamento da configuração do servidor:

  • nós queremos apenas um único repositório
  • deve ser possível enviar facilmente alterações para o controle remoto central
  • changesets devem conter o verdadeiro autor

Existe uma boa maneira de ter toda a configuração em um repositório e ter apenas um subcaminho como cópia de trabalho? Atualmente, estou considerando duas abordagens, mas queria fazer essa pergunta aqui primeiro

  1. Se o repositório .git estiver em um local fixo, por exemplo, em algum lugar em / var , poderíamos vincular o subcaminho a partir do diretório de trabalho "target". O principal problema: eu não saberia uma maneira de "vincular" o arquivo / etc para outro diretório para importar apenas o conteúdo, exceto a simbolização de arquivos únicos
  2. Encontrei outra alternativa nessa questão do SO , sugerindo ter várias ramificações em um repositório. Isso certamente aumentaria a complexidade, mas eu podia nos ver tentando dessa maneira.

O uso do git em uma única máquina para o gerenciamento de arquivos de configuração funciona bem, mas acredito que deve haver alguém que o esteja usando da maneira que gostaríamos de usá-lo.

Obrigado
Kariem

Kariem
fonte

Respostas:

14

Eu usei algo assim antes; foi assim que funcionou.

Configuração do repositório

  1. Crie um repositório git, "etc_files".
  2. Crie uma ramificação para cada tipo de máquina, por exemplo, "servidor / www", "servidor / dev" etc.
    • O git suporta barras nos nomes das ramificações. Isso me ajuda a manter os galhos retos na minha cabeça.
    • Se você tiver poucas máquinas suficientes, poderá ter uma ramificação para cada máquina individual.
  3. Crie uma ramificação para cada parte da infraestrutura compartilhada, por exemplo, "modules / apache", "modules / cups" etc.
    • Essas ramificações destinam-se a manter arquivos iguais entre todas as máquinas, como /etc/resolv.conf. Esses seriam os arquivos que você mantém nos repositórios "svn: externals" agora.

Construindo uma nova máquina

  1. Em uma máquina nova, clone o repositório git e verifique a ramificação para esse tipo de máquina.
    • Faço disso um clone somente leitura para impedir que as pessoas cometam alterações nas máquinas de produção sem testar.
  2. Configure um trabalho cron para git pullrepo automaticamente todos os dias.

Alterando ramificações da máquina

Alterar o código em uma única ramificação da máquina é simples; apenas git checkouta ramificação apropriada em seu ambiente de desenvolvimento, faça as alterações e envie-as de volta ao repositório central. Todas as máquinas nessa ramificação receberão automaticamente as alterações na próxima vez que o trabalho cron for executado.

Alterando ramificações do módulo

Alterar o código para uma ramificação do módulo é apenas um pouco mais complicado, pois envolve duas etapas:

  1. git checkout o ramo do módulo apropriado
  2. Faça as alterações e confirme-as no servidor centralizado.
  3. git checkoutcada ramificação da máquina que usa essa ramificação do módulo e depois mescla a ramificação do módulo. O git descobrirá que você mesclou essa ramificação do módulo antes e só notará as mudanças que ocorreram desde o último pai comum.

Este método tem vantagens e desvantagens. Um benefício é que eu posso fazer uma alteração em uma ramificação de módulo e aplicá-la às ramificações da máquina necessárias, o que permite que a máquina ramifique que não fique com a versão mais antiga até que esteja pronta. A desvantagem, portanto, é que você deve se lembrar de mesclar a ramificação do módulo em cada ramificação da máquina que possa estar usando. Eu uso um script que atravessa a árvore de confirmação e faz isso automaticamente para mim, mas ainda pode ser uma dor.


Como alternativa, as versões mais recentes do git suportam algo chamado " submódulos ":

Os submódulos permitem que repositórios externos sejam incorporados em um subdiretório dedicado da árvore de origem, sempre apontado para um commit específico.

Isso permitiria criar algo um pouco como as árvores "svn: externals", que você poderá atualizar da mesma maneira que faz agora.

Faz-tudo5
fonte
Esta é uma elaboração muito detalhada da alternativa 2 que sugeri na pergunta. Ótimo! No entanto, é difícil implementar o segundo requisito (retornando as alterações), se a raiz do repositório precisar estar por /causa das permissões de gravação.
Kariem
Você quer dizer permissões de gravação para / etc? Ou para poder se comprometer com o repositório? Receio não entender de onde vem o problema.
Handyman5
@ Handyman5: On a new machine, clone the git repo and check out the branch for that machine type. Posso tornar outras ramificações inacessíveis (por motivos de segurança)?
Eugene Yarmash
Você pode usar algo assim para exportar o conteúdo do repositório git para as máquinas. Então cada máquina não teria o repositório, apenas os arquivos em sua ramificação. No entanto, se você deseja enviar conjuntos de alterações para o controle remoto central de cada máquina, não conheço nenhuma solução que tenha um único repositório e também permita que você configure controles de acesso em várias ramificações. Talvez você possa fazer o Subversion sobre http com .htaccess no repositório? Não faço ideia se isso funciona.
Handyman5
@ Handyman5: Parece que a subversão é de fato a ferramenta certa para a tarefa. Obrigado pela ajuda.
Eugene Yarmash
1

Um pouco problemático aqui, mas parece que um gancho de recebimento de mensagens poderia fazer o trabalho

O repositório mestre é armazenado em / var / master
no clone do gancho para / var / localclone
e copia os detalhes específicos do host.
Você precisaria configurar o gancho .git / post-receive localmente em cada servidor (com as configurações apropriadas)

Também parece que você deseja algo mais como fantoche ou chef do que git, pois isso permitirá que você execute o git para gerenciar as configurações e os módulos centralmente e faça com que o puppet \ chef gerencie a implantação e a verificação para você

Tacticus
fonte
1

Aqui está um trabalho rápido que eu pensei:
1. Tenha um repositório central, digamos, /var/repo
2. Coloque os arquivos que são globais para todos os domínios nesse diretório.
3. Crie ramificações para cada subdomínio /var/repo/subdomain1, /var/repo/subdomain2etc.
4. Crie um gancho de postagem onde qualquer push para a ramificação seja mesclado ao mestre.

Portanto, quando você altera a configuração, /var/repo/subdomain2ela é imediatamente mesclada com a master, para que você possa extrair o repositório inteiramente e ter todos os arquivos de configuração.
Quando você quiser extrair configurações individuais de subdomínios, basta puxar a ramificação apropriada.

Como você coloca seus arquivos de configuração /var/repo/*é um assunto completamente diferente (abas cron, eu posso pensar)

~ $

Sudhi
fonte