Projet

Général

Profil

Anomalie #5913

Gérer les services par groupe de conteneurs

Ajouté par Daniel Dehennin il y a plus de 10 ans. Mis à jour il y a plus de 10 ans.

Statut:
Fermé
Priorité:
Normal
Assigné à:
Catégorie:
-
Début:
27/08/2013
Echéance:
27/09/2013
% réalisé:

100%

Temps passé:
Distribution:
EOLE 2.4

Description

Actuellement, les services sont gérés par conteneur ce qui provoque une double action en cas de mode non conteneur (#5641).

Il faudrait gérer par groupe de conteneur avec du code équivalent à creole.template.instance_files() (creole:source:creole/template.py?rev=7d41d59a#L474).


Demandes liées

Lié à python-pyeole - Anomalie #6105: Le script "courier-authdaemon" n'a pas de status Fermé 24/09/2013 27/09/2013
Lié à python-pyeole - Anomalie #6148: Les services sont désactivés puis réactivés au reconfigure Fermé 01/10/2013 04/10/2013
Dupliqué par python-pyeole - Evolution #5912: Factoriser/éclaircir le code de gestion des services Fermé 27/08/2013 27/09/2013
Bloque creole - Anomalie #5641: Un service déclaré dans 2 conteneurs différents démarre 2 fois en mode non conteneur Fermé 28/08/2013 27/09/2013

Révisions associées

Révision b4f231c9 (diff)
Ajouté par Daniel Dehennin il y a plus de 10 ans

Nouvelle API de gestion des services: « manage_service() »

Cette nouvelle API permet de gérer les services par groupe de conteneurs.

Il y a deux points d’entrées dans l’API :

- « manage_services() » pour appliquer une action sur une liste de
services ou tous par défaut ;

- « manage_service() » pour appliquer une action sur un service unique.

Chaque « method » de service doit définir une interface identique définie
par le dictionnaire « pyeole.service._ACTION_DISPATCHER ».

Un squelette est fourni dans « pyeole/service/method-skelton.txt » pour
faciliter la mise en œuvre d’une nouvelle méthode.

  • setup.py: Installation du nouveau paquet python « pyeole.service ».
  • pyeole/service/__init__.py: Point d’entrée définissant les deux
    fonctions « manage_services() » et « manage_service() ».
  • pyeole/service/error.py: Exceptions de « pyeole.service ».
  • pyeole/service/_apache.py: Gère les services de type « apache ».
  • pyeole/service/_network.py: Gère le service réseau sur le contrôleur
    LXC.
  • pyeole/service/_service.py: Gère les service de type « System V ».
  • pyeole/service/_upstart.py: Gère les service de type « upstart ».
  • pyeole/service/method-skelton.txt: Squelette de gestionnaire de
    service, basé sur le code de « upstart ».

Fixes: #5912 @48h
Fixes: #5913 @32h

Révision bd8714f2 (diff)
Ajouté par Daniel Dehennin il y a plus de 10 ans

Seul le code « 0 » défini un service System V fonctionnel

  • pyeole/service/_service.py (_do_sysv): Le code de status doit
    être « 0 ».

Ref: #6105
Ref: #5913

Révision e22e5692 (diff)
Ajouté par Daniel Dehennin il y a plus de 10 ans

Ne pas forcer 1 seconde d’attente après une action de service

  • pyeole/service/_service.py (_do_sysv): Suppression de l’appel « sleep ».

Ref: #5913
Ref: #6085
Ref: #6086

Historique

#1 Mis à jour par Daniel Dehennin il y a plus de 10 ans

Je ne vois pas bien comment m’en sortir avec le code existant (#5912).

Du coup, je ferais bien une nouvelle API gérant à la fois l’activation/désactivation et le lancement/arrêt des services ;-)

  • manage_service(action, name, container=None)
  • manage_services(action, names=None, container=None)

Ces deux fonctions gèrent la logique conteneur/groupe de conteneurs et passent le relais à une fonction qui fait le travail _manage_service(action, service, container=None) en dispatchant par action/méthode sur d’autres fonctions privées.

Étant donné que le code actuel de service_out() (source:pyeole/service.py?rev=a4b43345#L697) ne peut pas fonctionner, je me pose la question de l’intérêt de la double gestion.

#2 Mis à jour par Daniel Dehennin il y a plus de 10 ans

  • Statut changé de Nouveau à En attente d'informations

Tout commentaire est le bienvenu avant de modifier quoique ce soit.

#3 Mis à jour par Daniel Dehennin il y a plus de 10 ans

L’API donne à peu près ça :

_ACTION_DISPATCHER = {'enable': '_enable_service',
                      'disable': '_disable_service',
                      'status': '_status_service',
                      'start': '_start_service',
                      'stop': '_stop_service',
                      'restart': '_restart_service',
                      'reload': '_reload_service'}

def manage_services(action, names=None, container=None):
    """Apply :data:`action` to services.

    If no service :data:`names` is provided, :data:`action` is
    performed for all services.

    if no :data:`container` is provided, services are looked-up in all
    container groups.

    :param action: action to perform
    :type action: `str` in [``enable``, ``disable``, ``status``,
                  ``start``, ``restart``, ``stop``, ``reload``,
                  ``force-reload``]
    :param names: names of services
    :type names: `list` of `str`
    :param container: name of the container where to perform :data:`action`
    :type container: `str`

    """ 
    containers_ctx = []
    if container is not None:
        containers_ctx = [creole_client.get_container_infos(container)]
    else:
        for group_name in creole_client.get_groups():
            containers_ctx.append(creole_client.get_group_infos(group_name))

    for ctx in containers_ctx:
        _manage_service(action, services=names, ctx=ctx)

def manage_service(action, name, container=None):
    """Apply :data:`action` to one service.

    if no :data:`container` is provided, services are looked-up in all
    container groups.

    :param action: action to perform
    :type action: `str` in [``enable``, ``disable``, ``status``,
                  ``start``, ``restart``, ``stop``, ``reload``,
                  ``force-reload``]
    :param name: name of service
    :type name: `str`
    :param container: name of the container where to perform :data:`action`
    :type container: `str`

    """ 
    containers_ctx = []
    if container is not None:
        containers_ctx = [creole_client.get_container_infos(container)]
    else:
        for group_name in creole_client.get_groups():
            containers_ctx.append(creole_client.get_group_infos(group_name))

    for ctx in containers_ctx:
        _manage_service(action, services=[name], ctx=ctx)

def _manage_service(action, services, ctx):
    """Apply :data:`action` to :data:`services` in a container.

    :param action: action to perform
    :type action: `str` in [``enable``, ``disable``, ``status``,
                  ``start``, ``restart``, ``stop``, ``reload``,
                  ``force-reload``]
    :param services: names of service
    :type services: `list` of `str`
    :param ctx: container context
    :type ctx: `dict`

    """ 
    if _ACTION_DISPATCHER.get(action, None) is None:
        raise ValueError('Invalid action {0}'.format(action))

    services_ctx = []
    if services is None:
        services_ctx = ctx['services']
    else:
        for service in ctx['services']:
            if service['name'] in services:
                services_ctx.append(service)

    for service in services_ctx:
        globals().get(_ACTION_DISPATCHER[action])(service, ctx=ctx)

def _enable_service(service, ctx):
    log.debug("Enable service {0}".format(service['name']))
    creole_update_rcd(service, 'set', ctx)

def _disable_service(service, ctx):
    log.debug("Disable service {0}".format(service['name']))
    creole_update_rcd(service, 'remove', ctx)

def _status_service(service, ctx):
    log.debug("Status service {0}".format(service['name']))
    pass

def _start_service(service, ctx):
    log.debug("Start service {0}".format(service['name']))
    pass

def _stop_service(service, ctx):
    log.debug("Stop service {0}".format(service['name']))
    pass

def _restart_service(service, ctx):
    log.debug("Restart service {0}".format(service['name']))
    pass

def _reload_service(service, ctx):
    log.debug("Reload service {0}".format(service['name']))
    pass

#4 Mis à jour par Daniel Dehennin il y a plus de 10 ans

  • Assigné à mis à Daniel Dehennin
  • Début mis à 27/08/2013
  • % réalisé changé de 0 à 70

Merci de faire une relecture de source:pyeole/service.py?rev=feature/manage-services-per-group

Il s’agit d’une réécriture :

  • pas de gestion de l’affichage des OK/FAIL pour l’intant
  • pas de gestion des méthodes autres que service (sysV-init) et upstart

Les fonctions par méthodes devraient être regroupées dans des bibliothèques dédiés afin de ne pas trop mélanger le code et de permettre d’ajouter facilement de nouvelle méthodes (avec fabrique et tout le tintouin)

#6 Mis à jour par Daniel Dehennin il y a plus de 10 ans

  • % réalisé changé de 70 à 80

Un commit de plus afin d’ajouter une couche de compatibilité avec l’ancien code et les deprecated qui vont bien.

Toujours le même lien source:pyeole/service.py?rev=feature/manage-services-per-group

#7 Mis à jour par Daniel Dehennin il y a plus de 10 ans

Je viens de découper pyeole.service en un paquet:

TODO

  • pyeole.service._apache to manage Apache web sites
  • pyeole.service._eoleflask to manage eoleflask applications
  • pyeole.service._network to manage network which requires quite lot of special things :-/

#8 Mis à jour par Daniel Dehennin il y a plus de 10 ans

J’ai modifié la commande creole:source:bin/CreoleService?rev=feature/service-by-group afin d’utiliser la nouvelle API.

Je note en passant que si l’action à appliquée au service était en premier argument on pourrait faire :

root@server:~# CreoleService <action> <service1> <service2> ...<serviceX>

au lieu de :

root@server:~# for service in <service1> <service2> ...<serviceX>; do CreoleService <action> $service; done

Ce qui serait nettement moins coûteux (requête CreoleClient entre autre).

#9 Mis à jour par Daniel Dehennin il y a plus de 10 ans

J’ai ajouté un squelette afin d’aider à la gestion d’un nouveau service source:pyeole/service/_method_skelton.py?rev=feature/manage-services-per-group)

Si vous souhaitez écrire la gestion des services Apache, eoleflask et d’autres… ;-)

#10 Mis à jour par Daniel Dehennin il y a plus de 10 ans

  • Version cible mis à Eole 2.4-alpha

C’est bien parti pour être finalisable ;-)

#11 Mis à jour par Joël Cuissinat il y a plus de 10 ans

  • Version cible changé de Eole 2.4-alpha à Eole 2.4-alpha2

#12 Mis à jour par Daniel Dehennin il y a plus de 10 ans

  • Echéance mis à 27/09/2013
  • % réalisé changé de 80 à 90

Un paquet experimental est disponible en version 2.4.0-58~1.gbp52691a.

Dernière possibilité de relecture et de test ! Intégration la semaine prochaine !

#13 Mis à jour par Daniel Dehennin il y a plus de 10 ans

  • Statut changé de En attente d'informations à Résolu
  • % réalisé changé de 90 à 100

#14 Mis à jour par Joël Cuissinat il y a plus de 10 ans

  • Statut changé de Résolu à Fermé

Bon travail :)

Formats disponibles : Atom PDF