Use git para múltiples archivos de configuración del servidor

14

Hemos migrado una gran cantidad de código fuente a git y estamos muy contentos con nuestra solución actual. Nos gustaría tener nuestros archivos de configuración del servidor versionados en el mismo sistema, pero hay algunas cosas que no funcionan de la manera que nos gustaría y espero que alguien pueda compartir su experiencia aquí.

Esta pregunta es similar a ¿ Usar el control de revisión para los archivos de configuración del servidor? , pero tenemos algunos requisitos especiales que no funcionan con las sugerencias sobre esa pregunta.

La configuración actual usa subversion para los archivos de configuración. El repositorio correspondiente se parece a esto

 / # raíz del repositorio
 + - www.domain.com/ # configuración para www
 El | \ - etc /
 El | \ - apache2 /
 + - dev.domain.com/ # configuración para dev
 El | + - etc /
 El | \--optar/
 El | \ - app1 /         
 El | \ - configuración conf / # para app1 en dev
 \ - staging.domain.com/ # configuración para la puesta en escena

Con subversion esto funcionaría bien, porque es posible simplemente verificar un subdirectorio de un repositorio. Además, puede usar svn: externals para señalar una estructura común para varias configuraciones de configuración diferentes. Solo tuvimos que lidiar con los archivos .svn en todos los directorios versionados. Git, por otro lado , no tiene svn: las comprobaciones externas y dispersas siempre requieren que la ruta desde la raíz al directorio real sea la misma.

Al analizar la migración a git, traté de escribir los requisitos principales para el control de versiones de configuración del servidor:

  • solo queremos un repositorio único
  • debería ser posible empujar fácilmente los cambios al control remoto central
  • los conjuntos de cambios deben contener el autor real

¿Hay una buena manera de tener toda la configuración en un repositorio y solo tener una subruta como copia de trabajo? Actualmente estoy considerando dos enfoques, pero quería hacer esta pregunta aquí primero

  1. Si el repositorio .git está en una ubicación fija, por ejemplo, en algún lugar de / var , podríamos vincularnos a la subruta desde el directorio de trabajo "objetivo". El problema principal: no sabría una forma de "vincular" desde / etc a otro directorio para importar solo el contenido, excepto la simulación de archivos individuales
  2. Encontré otra alternativa en esta pregunta SO , sugiriendo tener múltiples ramas en un repositorio. Esto ciertamente aumentaría la complejidad, pero podría vernos intentarlo de esta manera.

El uso de git en una sola máquina para la gestión de archivos de configuración funciona bien, pero creo que debe haber alguien que lo esté usando de la forma en que nos gustaría usarlo.

Gracias
Kariem

Kariem
fuente

Respuestas:

14

He usado algo como esto antes; Así es como funcionó.

Configuración de repositorio

  1. Cree un repositorio de git, "etc_files".
  2. Cree una rama para cada tipo de máquina, por ejemplo, "servidor / www", "servidor / desarrollador", etc.
    • git admite barras en los nombres de las ramas. Esto me ayuda a mantener las ramas rectas en mi cabeza.
    • Si tiene pocas máquinas suficientes, podría tener una rama para cada máquina individual.
  3. Cree una rama para cada pieza de infraestructura compartida, por ejemplo, "módulos / apache", "módulos / tazas", etc.
    • Estas ramas son para contener archivos que son iguales entre todas las máquinas, como /etc/resolv.conf. Estos serían los archivos que mantiene en repositorios "svn: externals" ahora.

Construyendo una nueva máquina

  1. En una máquina nueva, clone el repositorio de git y revise la rama para ese tipo de máquina.
    • Hago de este un clon de solo lectura para evitar que las personas cometan cambios desde las máquinas de producción sin realizar pruebas.
  2. Configure un trabajo cron para realizar automáticamente git pullel repositorio todos los días.

Cambio de ramas de la máquina

Cambiar el código en una sola rama de máquina es simple; solo git checkoutla rama apropiada en su entorno de desarrollo, realice los cambios y vuelva a enviarlos al repositorio central. Todas las máquinas en esa rama recibirán los cambios automáticamente la próxima vez que se ejecute el trabajo cron.

Cambio de ramas del módulo

Cambiar el código para una rama de módulo es solo un poco más complicado, ya que implica dos pasos:

  1. git checkout la rama del módulo apropiado
  2. Realice sus cambios y confírmelos al servidor centralizado.
  3. git checkoutcada rama de la máquina que usa esa rama del módulo, y luego fusionar la rama del módulo en ella. git descubrirá que ha fusionado esa rama del módulo antes y solo notará los cambios que ocurrieron desde ese último padre común.

Este método tiene beneficios y desventajas. Un beneficio es que puedo hacer un cambio en una rama del módulo y aplicarlo a las ramas de la máquina que lo necesitan, lo que permite que las ramas de la máquina que no permanecen con la versión anterior hasta que estén listas. El inconveniente, entonces, es que debe recordar fusionar la rama de su módulo en cada rama de máquina que pueda estar usándola. Utilizo un script que atraviesa el árbol de confirmación y automáticamente hace esta fusión para mí, pero aún puede ser un dolor.


Como alternativa, las versiones más nuevas de git admiten algo llamado " submódulos ":

Los submódulos permiten que los repositorios foráneos se incrusten dentro de un subdirectorio dedicado del árbol de origen, siempre apuntando a una confirmación particular.

Esto le permitiría construir algo parecido a los árboles "svn: externos", que luego podría actualizar de la misma manera que lo hace ahora.

Manitas5
fuente
Esta es una elaboración muy detallada sobre la alternativa 2 que sugerí en la pregunta. ¡Excelente! Sin embargo, es difícil implementar el segundo requisito (retrasar los cambios), si la raíz del repositorio debe estar activada /debido a los permisos de escritura.
Kariem
¿Quieres decir permisos de escritura en / etc? ¿O para poder comprometerse con el repositorio? Me temo que no entiendo de dónde viene el problema.
Handyman5
@ Handyman5: On a new machine, clone the git repo and check out the branch for that machine type. ¿Puedo hacer que otras sucursales sean inaccesibles (por razones de seguridad)?
Eugene Yarmash
Podría usar algo como esto para exportar el contenido del repositorio git a las máquinas. Entonces cada máquina no tendría el repositorio, solo los archivos en su rama. Sin embargo, si desea enviar los conjuntos de cambios al control remoto central desde cada máquina, no conozco ninguna solución que tenga un solo repositorio y que también le permita configurar controles de acceso en varias ramas. ¿Quizás podría hacer Subversion sobre http con .htaccess en el repositorio? No tengo idea si eso funciona.
Handyman5
@ Handyman5: Parece que la subversión es, de hecho, la herramienta adecuada para la tarea. Gracias por tu ayuda.
Eugene Yarmash
1

Un poco molesto, pero parece que un gancho de recepción podría hacer el trabajo

El repositorio principal se almacena en / var / master,
el enlace lo clona en / var / localclone y
luego copia los detalles específicos del host. Debería
configurar el enlace .git / post-recepción localmente en cada servidor (con la configuración adecuada)

También parece que quiere algo más como títere o chef que git para esto, esto le permitiría ejecutar git para administrar las configuraciones y módulos de forma centralizada y hacer que puppet \ chef administre la implementación y la verificación por usted

Tacticus
fuente
1

aquí es un trabajo rápido en el que pensé
1. Tener un repositorio central en digamos /var/repo
2. Poner archivos que sean globales a todos los dominios en ese directorio.
3. Cree ramas para cada subdominio /var/repo/subdomain1, /var/repo/subdomain2etc.
4. Cree un enlace de publicación donde cualquier inserción a la rama se combine con el maestro.

Entonces, cuando cambie la configuración /var/repo/subdomain2, se fusionará inmediatamente con master para que pueda extraer el repositorio por completo y tener todos los archivos de configuración.
Cuando desee extraer configuraciones de subdominios individuales, simplemente extraiga la rama correspondiente.

Cómo poner sus archivos de configuración /var/repo/*es algo completamente diferente (pestañas cron, se me ocurre)

~ $

Sudhi
fuente