IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Django Python Discussion :

Thread - Arret simultanée serveur linux


Sujet :

Django Python

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    57
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 57
    Par défaut Thread - Arret simultanée serveur linux
    Bonjour,

    Je développe une interface qui permet d’éteindre un certain nombre de serveur linux de manière rapide et sans aller en ssh sur chacun. (environ 50).

    Pour cela, je développe sous django.

    J'ai cependant un problème, en effet, j'utilise des Thread pour exécuter la commande d'arrêt en simultanée sur l'ensemble des serveurs afin de maximiser le temps d'arrêt, mais lors du lancement du code, certains serveurs ne s'éteignent pas (je ne sais pas s'il est possible de voir la commande dans les logs des serveurs).

    Ci dessous le code (ou du moins la partie qui nous concernent).

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    ############ -THREAD ARRET TOTAL- ########################
    def th_arret_total(request,p1,p2, p3,p4, dechiffre_pwd):
        today = timezone.now()
        print "today UTC: %s" % today
     
        #p1 = param['serveur']
        #p2 = param['pwd']
        #p3 = param['ip']
        #p4 = param['username']
     
        cmd_arret = str('init 0')
     
        try:
            output = subprocess.check_output(['sshpass -p '+dechiffre_pwd+' ssh -o ConnectTimeout=2 '+p4+'@'+p3+ ' '+cmd_arret],shell=True,stderr=subprocess.STDOUT)  # LE shell=True permet d'executer avec des option ssh
            print "Sortie premiere commande: %s" % output
     
            print "\n----------Srv P: %s" % p1 +"---------------\n"
            print "Resultat %s : %s" % (p1,output)
     
            fichier_cnf = io.open(chemin_du_fichier_log, "a", encoding='utf8')
     
            fichier_cnf.write(u'{nl}{nl}********-LOG ARRET -*****************************\
                                {nl}date execution script = {date}\
                                {nl}Serveur = {p1}\
                                {nl}*************************************{nl}'.format(
                date=today,
                p1=p1,
                nl='\n')
            )
            fichier_cnf.close()
     
     
        except subprocess.CalledProcessError as grepexc:
            print "\nCode Erreur ", grepexc.returncode, grepexc.output
     
            fichier_cnf = io.open(chemin_du_fichier_log, "a", encoding='utf8')
     
            fichier_cnf.write(u'{nl}{nl}********-LOG ARRET (erreur)-*****************************\
                                {nl}date execution script = {date}\
                                {nl}Serveur = {p1}\
                                {nl}code erreur = {code_erreur}\
                                {nl}*************************************{nl}'.format(
                date=today,
                p1=p1,
                code_erreur=grepexc.output,
                nl='\n')
            )
            fichier_cnf.close()
     
     
            print type(grepexc.output), str(grepexc.output)
            erreur_verif_key = str('Host key verification failed.')
     
            # COMPARAISON DE RETOUR D'ERREUR "Host key verification failed." AVEC LA VARIBLE grepexc.output
     
            error1 = [(grepexc.output).decode("utf-8").rstrip('\n\r')]  # Permet de supprimer le retour chariot a la fin
     
            print "\n----------Srv P: %s" % p1 +"---------------\n"
            print 'Erreur_1: %s - %s' % (p1, error1)
     
            for place in error1:
                print ('Verification %s with %s: %s' % (place, erreur_verif_key, place == erreur_verif_key))
                print (place == erreur_verif_key)
     
            if (place == erreur_verif_key) == True:
                # SI L'ERREUR EST POSITIVE, ALORS ON ENTRE LA CLE ECDSA DANS LE FICHIER KNOW_HOST DE SSH
                output1 = str(
                    'sshpass -p ' + dechiffre_pwd + ' ssh -o StrictHostKeyChecking=no ' + p4 + '@' + p3 + ' exit')
                print output1
                os.system(output1)
     
                print "\n----------Srv P: %s" % p1 +"---------------\n"
                print('\nSortie Cle ECDSA: ', output1.decode('UTF-8'))
                # RENVOI DE LA COMMANDE DE MANIERE AUTOMATIQUE
                try:
                    output = subprocess.check_output(['sshpass -p '+dechiffre_pwd+' ssh -o ConnectTimeout=2 '+p4+'@'+p3+ ' '+cmd_arret], shell=True,
                                                     stderr=subprocess.STDOUT)
                    print('Sortie relance Cmd: ', output.decode('UTF-8'))
     
                    fichier_cnf = io.open(chemin_du_fichier_log, "a", encoding='utf8')
     
                    fichier_cnf.write(u'{nl}{nl}********-LOG ARRET (relance)-*****************************\
                                        {nl}date execution script = {date}\
                                        {nl}Serveur = {p1}\
                                        {nl}Sortie relance = {output}\
                                        {nl}*************************************{nl}'.format(
                        date=today,
                        p1=p1,
                        output=output,
                        nl='\n')
                    )
                    fichier_cnf.close()
     
                # SI ERREUR, AFFICHAGE DU MESSAGE D'ERREUR SUR LA PAGE "retour_global.html"
                except subprocess.CalledProcessError as grepexc:
                    print "\n----------Srv P: %s" % p1 +"---------------\n"
                    print "\nCode Generale", grepexc.returncode, grepexc.output
     
                    fichier_cnf = io.open(chemin_du_fichier_log, "a", encoding='utf8')
     
                    fichier_cnf.write(u'{nl}{nl}********-LOG ARRET (relance)-*****************************\
                                        {nl}date execution script = {date}\
                                        {nl}Serveur = {p1}\
                                        {nl}Sortie generale = {sortie_generale}\
                                        {nl}*************************************{nl}'.format(
                        date=today,
                        p1=p1,
                        sortie_generale=grepexc.output,
                        nl='\n')
                    )
                    fichier_cnf.close()
     
                    return render(request, 'retour_global.html', {'output': grepexc.output})
     
        except request.Timeout as err:
            print "TIMEOUT"
            print err.message
            pass
     
     
        except CalledProcessError:
            #return redirect('ping')
            return render(request, 'ping.html')
     
        except:
            print "PASS"
            pass
     
     
    def arret_total(request):
        print request.user.has_perm("sar.executer_commande_arret")
        if not request.user.has_perm("sar.executer_commande_arret"):
            return HttpResponse('The user is not superuser')
        else:
            # RECUPERATION FUSEAU HORAIRE FR
            PT = pytz.country_timezones['FR']
            print PT
     
            # HEURE AU FORMAT UTC
            today = timezone.now()
            print "today UTC: %s" % today
     
            # HEURE AU FORMAT UTC+1
            today_11 = timezone.localtime()
            print "today UTC+11: %s" % today_11
     
            delta_10min = timezone.now() + timedelta(minutes=10)
            print type(delta_10min)
     
            delta = delta_10min.strftime('%Y-%m-%d %H:%M')
            print "delta: %s" % delta
            print type(delta)
     
     
     
            if request.method == 'POST':
                arret_form = ArretTotalForm(request.POST)
                mastercode = MasterCodeForm(request.POST)
     
                if arret_form.is_valid() and mastercode.is_valid():
     
                    code1 = arret_form.cleaned_data['code1']
                    code2 = arret_form.cleaned_data['code2']
     
                    code_maitre = mastercode.cleaned_data['code_maitre']
     
     
                    try:
                        recup_date = ArretTotal.objects.get(Q(code1=code1) & Q(code2=code2)).date
     
                        verif_code_master = MasterCode.objects.values('code_maitre').filter(code_maitre__startswith='C')
     
     
                        for result in verif_code_master:
                            solution = result['code_maitre']
     
                            substring = "C"
     
                            print solution
     
                            if solution.find(substring) is not -1:
                                print 'solution %s' % solution
                            else:
                                print solution.find(substring)
                                messages.error(request, messages.INFO, "Error")
                                return render(request, 'arret_total.html', {'arret_form': arret_form, 'mastercode': mastercode})
     
                        print "recup_date"
                        print recup_date
     
                    except ObjectDoesNotExist:
                        return redirect('erreur_code_arret')
     
     
                    compare_heure = (today_11 - recup_date).seconds
                    print "compare_heure: %s" % compare_heure
                    print type(compare_heure)
     
                    if compare_heure < int(600) and solution == code_maitre:
     
                        liste_srv = Globale.objects.values('serveur', 'pwd', 'ip', 'username').exclude(type=10).exclude(type=9).order_by('priorite')
                        print liste_srv.query
     
     
                        for param in liste_srv:
     
                            p1 = param['serveur']
                            p2 = param['pwd']
                            p3 = param['ip']
                            p4 = param['username']
     
                            dechiffre_pwd = dechiffre.dechiffre(p2)
                            threading.Thread(target=th_arret_total, args=(request, p1,p2,p3,p4, dechiffre_pwd)).start()
     
     
     
                        # SUPPRESSION DES CODES 1 ET 2  ET DU CODE MAITRE DE LA BDD
                        lst = [Q(code1=code1), Q(code2=code2)]
     
                        obj = ArretTotal.objects.filter(reduce(AND,lst))
                        obj2 = MasterCode.objects.filter(code_maitre=code_maitre)
                        print obj.query
                        obj.delete()
                        obj2.delete()
     
                        # GENERATION D'UN NOUVEAU CODE MAITRE
                        generation_code_maitre = random.randrange(100000, 500000)
                        Exe = MasterCode(code_maitre= str('C')+str(generation_code_maitre))
                        Exe.save()
     
                        print request.user.email
     
                        # PERMET D'ENVOYER LE MAIL
                        perms = Permission.objects.get(codename='executer_commande_arret')
                        users = User.objects.get(username='admin').email
                        print 'users: %s' % users
     
     
                        sujet = 'CODE MAITRE'
                        message = 'Bonjour,\n' \
                                  'Voici le Code Maitre pour valider l\'arrêt :\n\n' \
                                  '######################## - CODE MAITRE - ########################\n\n' \
                                  'CODE MAITRE: C' + str(generation_code_maitre) + '\n\n' \
                                  '######################## - CODE MAITRE - ########################\n\n' \
                                  'Celui-ci n\'est valide que pour une seule utilisation, il est auto-généré.\n' \
                                  'Cette commande à été demandée par l\'utilisateur: ' + request.user.username + '.\n' \
                                 'Cdt\n' \
                                 '--Mail automatique ne pas répondre.--'
     
                        envoyeur = 'user@logtest.com'
                        destinataires = [users]
                        send_mail(sujet, message, envoyeur, destinataires)
     
                        return HttpResponseRedirect('ping')
            else:
                arret_form = ArretTotalForm()
                mastercode = MasterCodeForm()
     
            return render(request, 'arret_total.html', {'arret_form': arret_form, 'mastercode': mastercode})
    J'ai aussi cette erreur qui s'affiche lors de l'execution du script, généralement à la fin sur plusieurs lignes:
    Nom : Capture.PNG
Affichages : 130
Taille : 494,0 Ko

    J'ai bien conscience que mon code n'est pas parfait, mais cela pourra faire l'objet d'un second poste pour l'optimiser.

    Merci à vous

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 695
    Par défaut
    Salut,

    Moi ce que je vois est que vous développez sur de vieilles versions de Python et de Django qui ne sont plus supportées....

    Par ailleurs, le traceback ne permet pas de remonter au code que vous avez posté.

    J'espère que d'autres seront plus inspirés.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    57
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 57
    Par défaut
    Bonjour,

    Il s'agit de python 2.7 avec une version de django 1.7 (certes plus supportée mais qui fonctionne encore)
    Pour ce qui est du traceback, en principe il correspond au code ci dessus, en tout cas il apparait lors de l’exécution de celui-ci.

    Il y a juste ces deux lignes au dessus de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    @login_required(login_url='/sar/login/')
    @permission_required('sar.executer_commande_arret')
     
    def arret_total(request):
    Merci

  4. #4
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 339
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 339
    Par défaut
    Au peu que l'on voit, cela semple être ton objet request qui pose problème.

  5. #5
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 695
    Par défaut
    Salut,

    Citation Envoyé par nico85 Voir le message
    Il y a juste ces deux lignes au dessus de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    @login_required(login_url='/sar/login/')
    @permission_required('sar.executer_commande_arret')
    Effectivement, çà semble planter dans l'exécution du décorateur qui semble être exécuté dans le contexte d'un thread.

    Personnellement, évitant ce genre de mélange par expérience, ma compréhension est assez biaisée: sachant pourquoi je n'écris pas çà, je ne suis pas surpris que çà ne fonctionne pas... et pas plus convaincu que çà de l'intérêt de comprendre comment faire marcher votre code en l'état.

    Désolé.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    57
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 57
    Par défaut
    Salut,
    Merci pour ce conseil, je vais tenté de supprimer le decorateur, et voir le résultat

  7. #7
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 049
    Par défaut
    Bonjour,

    Je développe une interface qui permet d’éteindre un certain nombre de serveur linux de manière rapide et sans aller en ssh sur chacun.
    Pouvez-vous m'expliquer la stratégie adoptée alors ? Un serveur HTTP sera sur chaque serveur linux ?

    Vous savez que vous pouvez coder en python avec des applications comme Ansible et fabric qui utilise évidemment ssh ?

    Contrôler des serveurs linux sans ssh Je ne savais pas que ça se faisait, en tout cas dans le monde professionnel, je n'ai pas encore vu ça.

    Et si vous contrôler leur arrêt, quelque-soit le moyen, il faudra en trouver un autre pour les démarrer à nouveau ? Et un serveur, à moins d'un bug exceptionnel, ça ne s'arrête pas

    Je veux bien en savoir plus... ça m'intéresse.

  8. #8
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    57
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 57
    Par défaut
    @Fred1599:

    En faite, seule l'application est installer sur une serveur apache. Une fois les codes authentifications envoyés, le commande suivante est envoyé aux différents serveurs:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ['sshpass -p '+dechiffre_pwd+' ssh -o ConnectTimeout=2 '+p4+'@'+p3+ ' '+cmd_arret],shell=True,stderr=subprocess.STDOUT

    Concernant Ansible et Fabric, je ne connais pas trop mais je vais regarder.


    J'ai bien conscience que normalement on n’arrête pas un serveur, mais parfois c'est vital pour les protéger (pannes de courant et groupe électrogène défectueux). Pour les démarrer, je vais tenter un Wake on line, mais pour le moment c'est grace au bouton marche


    Cependant, mon script n'est pas parfait, je ne maitrise pas trop les class et autres ... et donc il arrive que certains serveurs ne s'éteignent pas (impossible de savoir s'ils ont reçu la commande "init 0"

  9. #9
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 695
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 695
    Par défaut
    Citation Envoyé par nico85 Voir le message
    J'ai bien conscience que normalement on n’arrête pas un serveur, mais parfois c'est vital pour les protéger (pannes de courant et groupe électrogène défectueux). Pour les démarrer, je vais tenter un Wake on line, mais pour le moment c'est grace au bouton marche
    Arrêter et démarrer proprement un groupe de serveurs est une opération de base côté gestion d'un parc de machine et pouvoir le faire "à distance" une fonctionnalité nécessaire...
    Et vous avez des tas de logiciels qui savent faire çà modulo des configuration matérielles ad hoc.

    Ce qui est surprenant ici, c'est que vous vous lancez dans une aventure sans trop rien maîtriser alors que des solutions prêtes à l'emploi existent déjà.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  10. #10
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 049
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 049
    Par défaut
    @nico85,

    Vous avez bien conscience d'utiliser ssh ? Du coup je ne comprend plus votre 1er message...

  11. #11
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    57
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 57
    Par défaut
    Bonjour,

    Ma question est de comprendre pourquoi mon code n'a pas l'aire de bien s'executer.

    Concernant les serveurs, je ne peux rien ajouter dessus, ceux-ci sont configurer pour écraser toutes nouvelles config. Du coup, j'ai trouvé ce moyen pour les eteindre de manière globale en cas de gros problème

Discussions similaires

  1. [InetAdress] isReachable : pb ping avec serveurs linux
    Par tck-lt dans le forum Entrée/Sortie
    Réponses: 8
    Dernier message: 23/08/2005, 18h28
  2. Réponses: 5
    Dernier message: 21/12/2004, 15h17
  3. Accéder à un serveur linux par son nom
    Par flatron dans le forum Réseau
    Réponses: 6
    Dernier message: 01/07/2004, 14h27
  4. Serveur Linux dans un environnement Windows
    Par Loth dans le forum Réseau
    Réponses: 6
    Dernier message: 29/05/2004, 10h29
  5. Serveur Linux avec clients Windows
    Par ostaquet dans le forum Installation
    Réponses: 2
    Dernier message: 01/08/2002, 15h40

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo