Quelle est la meilleure pratique pour gérer les informations spécifiques au système sous contrôle de version?

StackOverflow https://stackoverflow.com/questions/419322

Question

Le contrôle de version étant nouveau pour moi, je vous prie de m'excuser s'il existe une solution bien connue. Pour ce problème en particulier, j'utilise git, mais je suis curieux de savoir comment le gérer pour tous les systèmes de contrôle de version.

Je développe une application Web sur un serveur de développement. J'ai défini le nom de chemin absolu de l'application Web (pas la racine du document) à deux endroits. Sur le serveur de production, ce chemin est différent. Je suis confus quant à la façon de gérer cela.

Je pourrais soit:

  1. Reconfigurer le serveur de développement pour partager le même chemin que la production
  2. Modifiez les deux occurrences chaque fois que la production est mise à jour.

Je n'aime pas le numéro 1, car je préférerais que l'application reste flexible pour toute modification future. Je n’aime pas le n ° 2, car si je commençais à développer sur un deuxième serveur de développement avec un troisième chemin, je devrais le changer pour chaque commit et mettre à jour.

Quel est le meilleur moyen de gérer cela? J'ai pensé à:

  1. Utilisation de mots-clés personnalisés et de développement de variable (par exemple, définir la propriété $ PATH $ dans les propriétés du contrôle de version et l'étendre dans tous les fichiers). Git ne supporte pas cela parce que ce serait un énorme coup dur pour la performance.

  2. Utilisation des points d'ancrage post-mise à jour et pré-validation. Peut-être la solution probable pour git, mais chaque fois que je regardais l'état, il signalait que les deux fichiers étaient modifiés. Pas vraiment propre.

  3. Extraction du chemin d’un fichier de configuration en dehors du contrôle de version. Ensuite, je devrais avoir le fichier de configuration au même endroit sur tous les serveurs. Pourrait tout aussi bien avoir le même chemin pour commencer.

Existe-t-il un moyen simple de gérer cela? Est-ce que je pense trop?

Était-ce utile?

La solution

Ne JAMAIS coder de manière irréversible les données de configuration, telles que les chemins du système de fichiers, ni forcer la correspondance de plusieurs déploiements. C’est le côté obscur, où il y a beaucoup de souffrance.

Je trouve utile et facile de construire mes systèmes pour prendre en charge facilement plusieurs configurations, et je valide régulièrement les fichiers de configuration dans le contrôle de source, mais la production est obscurcie (aucun mot de passe réel) et le développement est basé sur un modèle (donc une checkout ne peut pas écraser la configuration d'un développeur). Le code est toujours empaqueté de manière indépendante de la configuration: le même fichier binaire peut être déployé n’importe où.

Malheureusement, la plupart des plates-formes de langage / développement ne supportent pas facilement cela (contrairement à Ruby on Rails). Par conséquent, vous devez le construire vous-même, à des degrés divers.

En général, le principe de base consiste à incorporer l'indirection dans votre configuration: ne spécifiez pas la configuration, mais comment trouver la configuration dans votre code. Et généralement invoquer plusieurs indirections: spécifique à l'utilisateur, spécifique à l'application, spécifique à la machine, spécifique à l'environnement. Chacune doit être trouvée dans un lieu / une manière bien défini, et il doit exister une priorité bien définie entre elles (généralement, utilisateur / machine plutôt qu'une application / environnement). Vous constaterez généralement que chaque paramètre configurable a une maison naturelle dans un emplacement, mais ne codez pas en dur cette dépendance dans vos applications.

Je trouve qu'il est TRÈS intéressant de concevoir des applications pour pouvoir rapporter leur configuration et la vérifier. Dans la plupart des cas, un élément de configuration manquant ou non valide doit entraîner l'abandon de l'application. Autant que possible, effectuez cette vérification (et abandonnez) au démarrage = échec rapide. Les codes par défaut ne sont codés en dur que lorsqu'ils peuvent être utilisés de manière fiable.

Résumez l’accès à la configuration de sorte que la plupart des applications n’ont aucune idée de son origine ni de la façon dont elle est traitée. Je préfère créer des classes Config qui exposent les paramètres configurables sous forme de propriétés individuelles (fortement typées le cas échéant), puis j'injecte " en classes d’application via IOC. Ne faites pas que toutes vos classes d'application invoquent directement le cadre de configuration brut de la plate-forme choisie. L'abstraction est ton amie.

Dans la plupart des organisations de classe entreprise (Fortune 500), personne ne voit les configurations de l’environnement de production (ni même de test) à l’exception de l’équipe d’administrateur de cet environnement. Les fichiers de configuration ne sont jamais déployés dans une version, ils sont édités à la main par l'équipe d'administration. Les fichiers de configuration pertinents ne sont certainement jamais archivés dans le contrôle de source parallèlement au code. L'équipe d'administration peut utiliser le contrôle de source, mais il s'agit de son propre référentiel privé. Les réglementations Sarbanes-Oxley et autres réglementations similaires ont également tendance à interdire formellement aux développeurs l'accès général aux systèmes de (presque) production ou à toute donnée de configuration sensible. Soyez attentif lorsque vous concevez votre approche.

Profitez.

Autres conseils

Vous devez toujours séparer l'historisation (à quoi sert un contrôle de code source) du déploiement.

Un déploiement implique:

  • un ensemble de données identifié (pour lequel une balise ou une étiquette fournie par le SCM est utile)
  • un processus manipulant ces données (pour au moins les copier au bon endroit, mais aussi développer certains fichiers compressés, etc.)

Parmi les différentes opérations d’un déploiement, vous devez inclure une phase de dé-variabilisation .

Une variable est un mot-clé représentant tout ce qui est susceptible de changer en fonction de votre plate-forme de déploiement (un PC pour l'intégration continue, un Linux pour l'homologation de base, un ancien Solaris8 pour l'homologation de pré-production et un Full F15K Solaris10 avec des zones pour la production: bref cela peut varier beaucoup). Voir la réponse de Jonathan Leffler pour des exemples pratiques.

Une variable peut représenter un chemin d'accès, une version de JVM, certains paramètres de JVM, etc., et ce que vous mettez dans un GDS doit être une donnée contenant des variables, jamais des paramètres codés en dur.

L'étape suivante consistera à inclure dans votre exécutable un moyen de détecter tout changement dans un fichier de paramètres afin de le mettre à jour lors de l'exécution de certains paramètres (en évitant la séquence "Tout arrêter / modifier les paramètres / redémarrer").
Cela signifie qu'elles sont deux types de variables de déploiement :

  • statiques (qui ne changeront jamais),
  • dynamiques (à prendre en compte idéalement lors de la session d'exécution)

Évitez autant que possible les chemins absolus.

Ne vous fiez pas à votre contrôle de version actuel pour faire quelque chose de magique - vous pourrez changer de système de contrôle de version à l'avenir.

L’approche la plus simple fonctionne pour moi: avoir un 'config.live' et le 'config' est configuré pour le développement. Pendant le déploiement, déplacez simplement config.live vers config et tout va bien. Pour des configurations plus complexes, un sous-répertoire peut être requis pour chaque configuration.

Un ensemble de procédures de déploiement est essentiel car la configuration n'est qu'un domaine différent.

N'importe quoi de plus complexe est presque certainement susceptible de causer plus de problèmes qu'il n'en résout.

Utilisez un GDS tel que Git pour le contrôle de version et un outil de déploiement tel que Capistrano pour déploiement . Bien que Capistrano ait été créé à l’origine pour Ruby on Rails, il n’est pas inutile de l’utiliser pour d’autres frameworks et langages.

L'important, c'est qu'un outil de déploiement spécifique vous donnera toute la flexibilité nécessaire pour automatiser des tâches telles que les chemins d'accès des deux côtés.

J'aime la façon dont Ruby on Rails traite ce type de problème: les fichiers de configuration spécifiques à l'environnement. Rails prend en charge les connexions de base de données de développement, de test et de production contrôlées par la configuration dans le fichier database.yml. Voici un article de blog sur la création d’autres options de configuration spécifiques à l’environnement. Il s’agit de Rails mais peut vous donner quelques idées sur la façon de faire quelque chose de similaire pour votre environnement. http://usablewebapps.com/2008/09 / yaml-and-custom-config-for-rails-projects /

On dirait que votre code de production est un référentiel complet sur git et pour mettre à jour la production, faites-vous un git pull ? Vous voudrez peut-être essayer un processus de génération distinct qui extrait le code de votre référentiel et crée une nouvelle génération (pas de dossier .git). Vous pourriez avoir des fichiers de configuration spécifiques à l’environnement contenant vos chemins copiés ou créés avec.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top