Au moment de la rédaction, la branche v2 a une classe Group
qui devrait être capable de servir d'unités anciennement connues sous le nom de "rôles", alias "un groupe d'hôtes pour faire des choses avec/sur".
Cependant, il n'y a pas encore de moyen spécifique d'organiser ou d'étiqueter les objets Group
; c'est assez "fait" pour le cas d'utilisation de l'API pure des utilisateurs avancés qui souhaitent utiliser leur propre manière spécifique de les créer, mais il manque quelque chose pour les utilisateurs orientés CLI ou les personnes intermédiaires qui veulent quelque chose de framework à construire.
En d'autres termes, à moins que vous ne rouliez uniquement avec l'API, avoir des objets Group quelque part est inutile si la CLI ou les bits d'appel de tâche n'ont aucun moyen de les trouver !
Dans la v1, les rôles étaient en fait un seul espace de noms plat mappant des étiquettes de chaîne simples à ce qui serait des groupes dans la v2, et ils pouvaient être sélectionnés sur l'interface de ligne de commande au moment de l'exécution ( fab --roles=web,db
) et/ou enregistrés comme cibles par défaut pour les tâches ( @task('db') \n def migrate():
), un peu comme les hôtes.
Les utilisateurs les ont définis dans env.roledefs
, un simple dict ; toute fonctionnalité intermédiaire à avancée tournait autour de sa modification, généralement au moment de l'exécution (via une pré-tâche ou un sous-programme), parfois au moment du chargement du module.
Group
s et/ou Connection
s.Lexicon
au lieu d'un dict
.db
, web
, lb
, mais ensuite un nom de deuxième niveau appelé prod
qui est toujours l'union des trois autres. J'oublie si j'ai encore ajouté cela à Lexicon
. Il est possible qu'il existe d'autres sous-classes de cartes qui le font déjà aussi.if cxn in group
fonctionnerait même si cxn
est un objet distinct du membre égal à l'intérieur de group
.db
"@group
comme @task
, et les fonctions ne sont pas des unités de travail exécutables, mais produisent à la place des objets Group.À partir de la liste de diffusion :
Nous avons mis en place notre propre API REST interne qui remplit env.roledefs de manière dynamique en fonction du projet en cours de déploiement et dépend fortement du fait de ne pas intégrer les chaînes d'hôte dans le fabfile du projet ou de les spécifier dans la CLI.
Nos cas d'utilisation sont :
EnvironmentDatabaseAPIClient(
'https://rest.api.url/schema/',
env.service_name,
).apply_env()
Nombre d'environnements de serveurs - plusieurs environnements de test (certains d'entre eux sont privés, d'autres publics) et plusieurs environnements de production (pour différents clients). Chaque environnement se compose d'un ou plusieurs hôtes et est mappé au rôle Fabric.
Chaque service ( env.service_name
dans l'exemple ci-dessus) a un ensemble d'environnements différent.
Nous avons aussi des méta-rôles (groupes de rôles). Ils sont préfixés par group-
: group-production
, group-test
, group-external
, group-internal
, group-all
. Cela nous permet de déployer sur plusieurs rôles de serveur sans les spécifier un par un, par exemple group-all
déploie sur tous les rôles, à la fois en production et en test.
Nous avons des tâches Fabric spéciales pour imprimer des informations sur les groupes de rôles, les rôles et les hôtes.
Nous comptons également beaucoup sur le mappage inverse des chaînes d'hôtes vers les noms de rôle (les chaînes d'hôtes sont uniques par service_name). Ceci est utilisé pour la journalisation du déploiement et les notifications. Fondamentalement, nous enregistrons les déploiements de service sur chaque hôte et envoyons une notification Slack lorsque le service a été déployé sur tous les hôtes d'un rôle. Le serveur EnvironmentDatabaseAPI en est responsable (il conserve les journaux et l'état du déploiement). Cela se fait en décorant les tâches de tissu avec un décorateur qui soumet env.host
, env.port
et env.service_name
(plus les informations de validation) au serveur API.
Nous prévoyons d'ajouter l'authentification de déploiement à l'avenir, également très probablement pour extraire plus env
variables
Merci @max-arnold ! Je reconnais également beaucoup de ceux de mes propres cas d'utilisation dans le passé. Le bit de mappage inverse en particulier, je me souviens d'être venu plusieurs fois dans la v1, je l'ai donc ajouté à la liste.
Pour que Fabric v2 me soit utile, j'aurais besoin d'un moyen de dire à fab
quel ensemble d'hôtes exécuter une tâche.
Auparavant, je définissais des rôles, puis exécutais fab -R ...
. (En fait, les rôles ont été définis par programme à l'aide d'une plage d'adresses IP, mais ce n'est pas une exigence et une liste statique dans un fichier YAML conviendrait.)
Je ne parviens pas à trouver d'équivalent dans Fabric v2 et je n'ai pas non plus réussi à émuler cette fonctionnalité en utilisant :
fabric.yaml
contenantactive_hostset: null
hostsets:
myhostset:
- ...
active_hostset = config["hostsets"][config["active_hostset"]]
en fabfile.py
env INVOKE_ACTIVE_HOSTSET=myhostset fab ...
Au lieu de la liste d'hôtes attendue, j'obtiens KeyError: 'active_hostset'
.
Nous mappons différents ensembles d'hôtes à chaque rôle pour chacun de nos environnements dans Fabric v1, et l'environnement est défini en exécutant une tâche role.environment:staging
pour le spécifier. Cette tâche influence donc les hôtes utilisés par les tâches suivantes.
Dans la v2, nous avons essayé d'utiliser une tâche personnalisée, mais le problème est que Executor.expand_calls
s'exécute avant l'exécution de notre tâche role.environment
et qu'aucune des tâches suivantes ne connaît l'environnement afin de créer dynamiquement ses listes d'hôtes.
Faire de Executor.expand_calls
un générateur permet à l'exécution des tâches d'influencer l'exécution des tâches ultérieures. Donc, mon exemple ci-dessus fonctionne, où nous avons un Task
qui doit connaître son environnement pour étendre correctement les rôles aux hôtes. par exemple fab role.environment dev deploy.app
- la tâche role.environment
est maintenant exécutée avant que deploy.app
soit étendu, et donc deploy.app
connaît l'environnement et peut configurer ses hôtes, puis est étendu dans le bon ensemble de tâches.
J'ai prototypé ceci dans mes forks:
https://github.com/pyinvoke/invoke/compare/master...rectalogic :expand-generator
https://github.com/fabric/fabric/compare/master...rectalogic :expand-generator
Salut, je ne sais pas ce qui est arrivé à ce logiciel après de nombreuses années, mais j'ai vraiment raté le concept de "rôles" dans [email protected] , surtout lors de l'exécution de $ fab -R dev
Nous utilisons également des rôles pour représenter le même ensemble d'opérations dans différents environnements. Peut-être que séparer le concept d'un rôle nommé et d'un environnement nommé serait utile ? Comme dans, le rôle Web dans l'environnement de développement.
Commentaire le plus utile
Salut, je ne sais pas ce qui est arrivé à ce logiciel après de nombreuses années, mais j'ai vraiment raté le concept de "rôles" dans [email protected] , surtout lors de l'exécution de
$ fab -R dev