Utiliser git pour plusieurs fichiers de configuration de serveur

14

Nous avons migré beaucoup de code source vers git et sommes très satisfaits de notre solution actuelle. Nous aimerions que nos fichiers de configuration de serveur soient versionnés sur le même système, mais il y a quelques choses qui ne fonctionnent pas comme nous le voudrions et j'espère que quelqu'un pourra partager son expérience ici.

Cette question est similaire à l' utilisation du contrôle de révision pour les fichiers de configuration du serveur? , mais nous avons des exigences particulières qui ne fonctionnent pas avec les suggestions sur cette question.

La configuration actuelle utilise subversion pour les fichiers de configuration. Le référentiel correspondant ressemble à ceci

 / # racine du référentiel
 + - www.domain.com/ # configuration pour www
 | \--etc/
 | \ - apache2 /
 + - dev.domain.com/ # configuration pour dev
 | + - etc /
 | \--opter/
 | \ - app1 /         
 | \ - configuration conf / # pour app1 sur dev
 \ - staging.domain.com/ # configuration pour le transfert

Avec subversion, cela fonctionnerait très bien, car il est possible de simplement extraire un sous-répertoire d'un référentiel. De plus, vous pouvez utiliser svn: externals pour pointer vers une structure commune pour plusieurs configurations de configuration différentes. Nous n'avons eu à gérer que les fichiers .svn dans tous les répertoires versionnés. Git, d'autre part, n'a pas svn: les externes et les extractions clairsemées nécessitent toujours que le chemin de la racine vers le répertoire réel soit le même.

Lors de la discussion de la migration vers git, j'ai essayé d'écrire les principales exigences pour la configuration du serveur versioning:

  • nous ne voulons qu'un seul référentiel
  • il devrait être possible de pousser facilement les modifications de la télécommande centrale
  • les ensembles de modifications doivent contenir le véritable auteur

Existe-t-il un bon moyen d'avoir toute la configuration dans un référentiel et de n'avoir qu'un sous-chemin comme copie de travail? Actuellement, j'envisage deux approches, mais je voulais d'abord poser cette question ici

  1. Si le dépôt .git est à un emplacement fixe, par exemple quelque part dans / var , nous pourrions créer un lien vers le sous-chemin à partir du répertoire de travail "cible". Le problème principal: je ne connais pas de moyen de "lier" de / etc à un autre répertoire afin d'importer uniquement le contenu, à l'exception de la liaison symbolique de fichiers uniques
  2. J'ai trouvé une autre alternative sur cette question SO , suggérant d'avoir plusieurs branches dans un référentiel. Cela augmenterait certainement la complexité, mais je pouvais nous voir essayer de cette façon.

L'utilisation de git sur une seule machine pour la gestion des fichiers de configuration fonctionne bien, mais je pense qu'il doit y avoir quelqu'un qui l'utilise de la façon dont nous aimerions l'utiliser.

Merci
Kariem

Kariem
la source

Réponses:

14

J'ai déjà utilisé quelque chose comme ça; c'est ainsi que cela a fonctionné.

Configuration du dépôt

  1. Créez un dépôt git, "etc_files".
  2. Créez une branche pour chaque type de machine, par exemple, "serveur / www", "serveur / dev", etc.
    • git prend en charge les barres obliques dans les noms de branche. Cela m'aide à garder les branches droites dans ma tête.
    • Si vous avez assez peu de machines, vous pouvez plutôt avoir une branche pour chaque machine individuelle.
  3. Créez une branche pour chaque élément de l'infrastructure partagée, par exemple "modules / apache", "modules / cups", etc.
    • Ces branches permettent de conserver des fichiers identiques sur toutes les machines, comme /etc/resolv.conf. Ce sont les fichiers que vous conservez maintenant dans les dépôts "svn: externals".

Construire une nouvelle machine

  1. Sur une nouvelle machine, clonez le dépôt git et vérifiez la branche pour ce type de machine.
    • J'en fais un clone en lecture seule pour empêcher les gens de valider les modifications des machines de production sans tester.
  2. Configurez un travail cron pour automatiquement git pullle repo tous les jours.

Changer les branches de la machine

Changer le code dans une seule branche de machine est simple; juste git checkoutla branche appropriée dans votre environnement de développement, apportez les modifications et validez-les dans le référentiel central. Toutes les machines de cette branche obtiendront automatiquement les modifications lors de la prochaine exécution du travail cron.

Modification des branches de module

La modification du code d'une branche de module n'est que légèrement plus délicate, car elle implique deux étapes:

  1. git checkout la branche de module appropriée
  2. Apportez vos modifications et validez-les sur le serveur centralisé.
  3. git checkoutchaque branche de machine qui utilise cette branche de module, puis fusionnez la branche de module en elle. git découvrira que vous avez fusionné cette branche de module auparavant et ne remarquera que les changements qui se sont produits depuis ce dernier parent commun.

Cette méthode présente à la fois des avantages et des inconvénients. Un avantage est que je peux apporter une modification à une branche de module et l'appliquer aux branches de machine qui en ont besoin, ce qui permet aux branches de machine qui ne restent pas avec l'ancienne version jusqu'à ce qu'elles soient prêtes. L'inconvénient est que vous devez vous rappeler de fusionner votre branche de module dans chaque branche de machine qui pourrait l'utiliser. J'utilise un script qui traverse l'arborescence de validation et effectue automatiquement cette fusion pour moi, mais cela peut toujours être pénible.


Comme alternative, les versions plus récentes de git supportent quelque chose appelé " sous-modules ":

Les sous-modules permettent aux référentiels étrangers d'être incorporés dans un sous-répertoire dédié de l'arborescence source, toujours pointé sur un commit particulier.

Cela vous permettrait de créer quelque chose d'un peu comme des arbres "svn: externals", que vous pourriez ensuite mettre à jour de la même manière que vous le faites maintenant.

Homme à tout faire5
la source
Il s'agit d'une élaboration très détaillée de la variante 2 que j'avais suggérée dans la question. Génial! Cependant, il est difficile d'implémenter la deuxième exigence (repousser les modifications), si la racine du référentiel doit être en /raison des autorisations d'écriture.
Kariem
Voulez-vous dire des autorisations d'écriture dans / etc? Ou pour pouvoir vous engager dans le référentiel? J'ai bien peur de ne pas comprendre d'où vient le problème.
Handyman5
@ Handyman5: On a new machine, clone the git repo and check out the branch for that machine type. Puis-je rendre d'autres succursales inaccessibles (pour des raisons de sécurité)?
Eugene Yarmash
Vous pouvez utiliser quelque chose comme ça pour exporter le contenu du référentiel git vers les machines. Ensuite, chaque machine n'aurait pas le référentiel dessus, juste les fichiers dans sa branche. Si vous souhaitez envoyer des ensembles de modifications à la télécommande centrale de chaque machine, je ne connais aucune solution qui possède à la fois un référentiel unique et vous permet également de configurer des contrôles d'accès sur différentes branches. Peut-être pourriez - vous faire Subversion sur http avec .htaccess sur le repo? Je ne sais pas si ça marche.
Handyman5
@ Handyman5: Il semble que la subversion soit en fait le bon outil pour la tâche. Merci de votre aide.
Eugene Yarmash
1

Un peu ici, mais cela ressemble à un crochet de réception de message pourrait faire le travail

Le référentiel maître est stocké dans / var / master,
le hook le clone dans / var / localclone,
puis copie les détails spécifiques à l'hôte.
Vous devrez configurer le hook .git / post-receive localement sur chaque serveur (avec les paramètres appropriés)

Il semble également que vous souhaitiez quelque chose de plus comme marionnette ou chef que git pour cela, cela vous permettrait d'exécuter git pour gérer les configurations et les modules de manière centralisée et que marionnette \ chef gère le déploiement et la vérification pour vous.

Tacticus
la source
1

voici un travail rapide auquel j'ai pensé
1. Avoir un référentiel central par exemple /var/repo
2. Mettez des fichiers qui sont globaux pour tous les domaines de ce répertoire.
3. Créez des branches pour chaque sous /var/repo/subdomain1- domaine , /var/repo/subdomain2etc.
4. Créez un crochet de publication où toute poussée vers la branche est fusionnée avec le maître.

Ainsi, lorsque vous changez de configuration, /var/repo/subdomain2il est immédiatement fusionné avec master afin que vous puissiez extraire entièrement le référentiel et avoir tous les fichiers de configuration.
Lorsque vous souhaitez extraire des configurations individuelles de sous-domaines, il suffit de tirer la branche appropriée.

Comment mettez-vous vos fichiers de configuration dans une /var/repo/*toute autre affaire (onglets cron, je peux penser)

~ $

Sudhi
la source