1
2
3
4
5
6
7
8
9
10
11
12
13 """Module gérant les actions sur les serveurs (via uucp)
14 """
15 from zephir.backend.db_utils import *
16 from zephir.backend.uucp_utils import uucp_pool, UUCPError, COMMANDS
17 from zephir.backend import config
18 from zephir.backend.config import u, log
19 from zephir.backend.xmlrpceole import XMLRPCEole as XMLRPC
20 from zephir.backend.lib_backend import AptChecker
21 from zephir.monitor.collecteur import AgentCollecteur, ServeurStatus
22 from zephir.lib_zephir import save_modes
23 from twisted.internet import defer, reactor, threads
24
25 import sys,os,shutil,time,smtplib,re,time,base64,glob,email
26 from email.header import Header
27 from datetime import datetime
28 import traceback
29 import psycopg2 as PgSQL
30 from cStringIO import StringIO
31
33 """serveur XMLRPC zephir pour la gestion des actions sur les serveurs
34 """
35
36 - def __init__(self,parent,agent_manager):
37 self.dbpool = db_connect()
38 self.dbpool.noisy = 0
39 XMLRPC.__init__(self)
40 self.agent_manager = agent_manager
41 self.parent=parent
42
43
44 self.scan_delay = config.SCAN_DELAY
45
46
47 self.start_time = str(time.time())
48
50 """met en queue des fichiers ou répertoires pour un serveur distant
51 et stocke la somme md5 des fichiers envoyés dans le fichier cheksum.txt du
52 systeme en question (dans zephir/conf/rne/serveur/)"""
53
54 id_uucp = str(serv.get_rne())+'-'+str(serv.id_s)
55
56 serveur_dir = serv.get_confdir()
57 cmd_tar = ['cd ',serveur_dir,';','/bin/tar','--same-owner','-chpf',archive+'.tar']
58
59 for fic in files:
60
61 if os.path.exists(os.path.join(serveur_dir,fic)):
62 cmd_tar.append(fic)
63 else:
64
65 if fic not in ['dico.eol','zephir.eol', 'droits_variante', 'droits_zephir']:
66
67 return 0, u("""fichier %s introuvable""" % os.path.join(serveur_dir,fic) )
68 cmd_tar.append('>/dev/null 2>&1')
69 res=os.system(" ".join(cmd_tar))
70 if res != 0:
71 return 0, u("""erreur de creation de l'archive %s.tar dans %s""" % (archive,serveur_dir))
72
73 cmd_checksum = """cd %s ;md5sum -b %s.tar > %s.md5""" % (serveur_dir,archive,archive)
74 os.system(cmd_checksum)
75 if uucp:
76
77 try:
78 res = uucp_pool.add_file(id_uucp,os.path.join(serveur_dir,archive+".tar"))
79 except UUCPError,e:
80 return 0, u("Erreur UUCP %s" % str(e))
81 return 1,u(archive+'.tar')
82
101
103 """prépare le redémarrage d'un service sur un groupe"""
104 erreurs=[]
105 old_clients=[]
106 for serveur in liste:
107 new_cli = False
108 if delay:
109 try:
110 id_serveur = int(serveur['id'])
111 serv = self.parent.s_pool.get(cred_user, id_serveur)
112 new_cli = serv.check_min_version(self.parent.maj_checker, 'zephir-client', '2.3-eole54~1')
113 except (KeyError, ValueError):
114 return 0, u("serveur inconnu dans la base zephir")
115 if new_cli:
116
117 retour = self.xmlrpc_service_restart(cred_user, serveur['id'], service, delay)
118 else:
119 retour = (1, "ok")
120 old_clients.append(id_serveur)
121 else:
122 retour = self.xmlrpc_service_restart(cred_user, serveur['id'], service, delay)
123 if retour[0] == 0:
124 erreurs.append(str(serveur['id'])+' : '+retour[1])
125 if erreurs != []:
126 return 0, u(erreurs)
127 else:
128 return 1, u(old_clients)
129
131 """exécution de la commande uucp pour redémarrer un service"""
132 try:
133 id_serveur = int(id_serveur)
134 serv = self.parent.s_pool.get(cred_user, id_serveur)
135 except (KeyError, ValueError):
136 return 0, u("serveur inconnu dans la base zephir")
137 else:
138 if delay != 0:
139 delay_opt = " %s" % str(delay)
140 else:
141 delay_opt = ""
142 id_uucp = str(serv.get_rne()) + '-' + str(id_serveur)
143
144 try:
145 uucp_pool.add_cmd(id_uucp,"zephir_client service_restart %s%s" % (service, delay_opt))
146 except UUCPError,e:
147 return 0, u("erreur uucp (%s)" % str(e))
148 return 1,u("ok")
149
151 """prépare le redémarrage d'un groupe de serveurs"""
152 erreurs=[]
153 for serveur in liste:
154 retour = self.xmlrpc_reboot(cred_user, serveur['id'], delay)
155 if retour[0] == 0:
156 erreurs.append(str(serveur['id'])+' : '+retour[1])
157 if erreurs != []:
158 return 0, u(erreurs)
159 else:
160 return 1, u('ok')
161
163 """exécution de la commande uucp pour redémarrer un serveur"""
164 try:
165 id_serveur = int(id_serveur)
166 serv = self.parent.s_pool.get(cred_user, id_serveur)
167 except (KeyError, ValueError):
168 return 0, u("serveur inconnu dans la base zephir")
169 else:
170 if delay != 0:
171 delay_opt = " %s" % str(delay)
172 else:
173 delay_opt = ""
174 id_uucp = str(serv.get_rne()) + '-' + str(id_serveur)
175
176 try:
177 uucp_pool.add_cmd(id_uucp,"zephir_client reboot%s" % delay_opt)
178 except UUCPError,e:
179 return 0, u("serveur %s : erreur uucp (%s)" % (str(id_serveur), str(e)))
180 return 1,u("ok")
181
182
188
204
274
276 """prépare la sauvegarde de configuration d'un serveur"""
277
278 return self._save_conf(cred_user, id_serveur, mode)
279
281 """prépare la sauvegarde de configuration d'un serveur"""
282 erreurs=[]
283 old_clients = []
284 for serveur in liste:
285 retour = self._save_conf(cred_user, serveur['id'], mode)
286 if retour[0] == 0:
287 erreurs.append(str(serveur['id'])+' : '+retour[1])
288 else:
289 old_clients.extend(retour[1])
290 if erreurs != []:
291 return 0, u(erreurs)
292 else:
293 return 1, u(old_clients)
294
296 """exécution de la commande uucp pour la mise à jour"""
297 try:
298 id_serveur = int(id_serveur)
299 serv = self.parent.s_pool.get(cred_user, id_serveur)
300 except (KeyError, ValueError):
301 return 0, u("serveur inconnu dans la base zephir")
302 else:
303 old_clients = []
304 id_uucp = str(serv.get_rne()) + '-' + str(id_serveur)
305
306
307 cmd_mode = ""
308 if serv.version != 'creole1' and mode in save_modes:
309
310
311 if serv.check_min_version(self.parent.maj_checker, 'zephir-client', '2.2-eole97'):
312 cmd_mode = " %s" % str(mode)
313 else:
314 old_clients.append(id_serveur)
315 try:
316 uucp_pool.add_cmd(id_uucp,"zephir_client save_files%s" % cmd_mode)
317 except UUCPError,e:
318 return 0, u("erreur uucp (%s)" % str(e))
319 return 1, (old_clients)
320
321 - def xmlrpc_maj(self,cred_user,id_serveur,reconf = 0, delay = "", options = ""):
322 """prépare la mise à jour d'un serveur Eole par l'intermédiare d'uucp"""
323
324 if delay > 0:
325
326 reconf = 0
327 return self._maj(cred_user, id_serveur, reconf, delay, options)
328
330 """prépare la mise à jour d'un groupe de serveurs Eole par l'intermédiare d'uucp"""
331 erreurs=[]
332 for serveur in liste:
333 retour = self._maj(cred_user, serveur['id'],reconf,delay,options)
334 if retour[0] == 0:
335 erreurs.append("serveur "+str(serveur['id'])+' : '+retour[1])
336 if erreurs != []:
337 return 0, u(erreurs)
338 else:
339 return 1, u('ok')
340
341 - def _maj(self, cred_user, id_serveur, reconf, delay,options):
342 """exécution de la commande uucp pour la mise à jour"""
343 try:
344 id_serveur = int(id_serveur)
345 serv = self.parent.s_pool.get(cred_user,id_serveur)
346 except (KeyError, ValueError):
347 return 0, u("serveur inconnu dans la base zephir")
348 else:
349 id_uucp = str(serv.get_rne()) + '-' + str(id_serveur)
350
351 try:
352 assert int(delay) > 0
353
354 reconf = 0
355 except:
356 delay = ""
357 try:
358 if serv.version == 'creole1':
359 uucp_pool.add_cmd(id_uucp,"zephir_client maj_auto %s" % (str(delay)))
360 else:
361 uucp_pool.add_cmd(id_uucp,"zephir_client maj_auto %s %s" % (str(delay), options))
362 except UUCPError, e:
363 return 0, u("Erreur UUCP (%s)" % str(e))
364
365
366
367 if reconf == 1:
368 return self.xmlrpc_reconfigure(cred_user, id_serveur)
369 else:
370 return 1, u("ok")
371
373 """prépare la mise à jour de zephir-client sur un serveur"""
374
375 return self._maj_client(cred_user, id_serveur)
376
378 """prépare la mise à jour de zephir-client sur un groupe de serveurs"""
379 erreurs=[]
380 for serveur in liste:
381 retour = self._maj_client(cred_user, serveur['id'])
382 if retour[0] == 0:
383 erreurs.append("serveur "+str(serveur['id'])+' : '+retour[1])
384 if erreurs != []:
385 return 0, u(erreurs)
386 else:
387 return 1, u('ok')
388
390 """exécution de la commande uucp pour la mise à jour de zephir-client"""
391 try:
392 id_serveur = int(id_serveur)
393 serv = self.parent.s_pool.get(cred_user,id_serveur)
394 except (KeyError, ValueError):
395 return 0, u("serveur inconnu dans la base zephir")
396 else:
397 id_uucp = str(serv.get_rne()) + '-' + str(id_serveur)
398
399 try:
400 uucp_pool.add_cmd(id_uucp,"zephir_client maj_client")
401 except UUCPError, e:
402 return 0, u("Erreur UUCP (%s)" % str(e))
403 else:
404 return 1, u("ok")
405
407 """stocke la configuration RVP d'un amon vers ce sphynx"""
408 try:
409 id_sphynx = int(id_sphynx)
410 id_amon = int(id_amon)
411 sphynx = self.parent.s_pool.get(cred_user,id_sphynx)
412 amon = self.parent.s_pool.get(cred_user,id_amon)
413 except (KeyError, ValueError):
414 return 0, u("serveur inconnu dans la base zephir")
415
416 cx = PgSQL.connect(database=config.DB_NAME,user=config.DB_USER,password=config.DB_PASSWD)
417 cursor=cx.cursor()
418 query = """select id_amon from conf_vpn where id_sphynx=%s"""
419 cursor.execute(query, (int(id_sphynx),))
420 data=cursor.fetchall()
421 cursor.close()
422 cx.close()
423
424 sphynx_dir = sphynx.get_confdir()
425 if not os.path.exists(sphynx_dir + os.sep + 'vpn'):
426 os.makedirs(sphynx_dir + os.sep + 'vpn')
427 archive = sphynx_dir + os.sep + 'vpn' + os.sep + str(id_amon) + '.tar.gz'
428
429 confs = [ligne[0] for ligne in data]
430 if int(id_amon) in confs:
431
432 query = """update conf_vpn set etat=%s where id_sphynx=%s and id_amon=%s"""
433 params = (0, int(id_sphynx), int(id_amon))
434 else:
435
436 query = """insert into conf_vpn (id_sphynx,id_amon,etat) values (%s,%s,%s)"""
437 params = (int(id_sphynx), int(id_amon), 0)
438 return self.dbpool.runOperation(query, params).addCallbacks(self._sphynx_add,db_client_failed,callbackArgs=[archive,content])
439
441 """écriture de la conf RVP"""
442 try:
443 file = StringIO()
444 data = base64.decodestring(content)
445 fd = open(archive,'wb')
446
447 file.write(data)
448 file.seek(0)
449 fd.write(file.read())
450 fd.close()
451 except:
452 return 0, u("erreur de sauvegarde de l'archive")
453 return 1, "OK"
454
456 """supprime la configuration RVP d'un amon vers ce sphynx"""
457 try:
458 id_sphynx = int(id_sphynx)
459 id_amon = int(id_amon)
460 sphynx = self.parent.s_pool.get(cred_user,id_sphynx)
461 amon = self.parent.s_pool.get(cred_user,id_amon)
462 except (KeyError, ValueError):
463 return 0, u("serveur inconnu dans la base zephir")
464 cx = PgSQL.connect(database=config.DB_NAME,user=config.DB_USER,password=config.DB_PASSWD)
465 cursor=cx.cursor()
466 query = """select etat from conf_vpn where id_sphynx=%s and id_amon=%s"""
467 params = (int(id_sphynx), int(id_amon))
468 cursor.execute(query, params)
469 data=cursor.fetchone()
470 etat = data[0]
471 cursor.close()
472 cx.close()
473 try:
474
475 sphynx_dir = sphynx.get_confdir()
476 archive = sphynx_dir + os.sep + 'vpn' + os.sep + str(id_amon) + '.tar.gz'
477 os.unlink(archive)
478 except:
479 if del_row == 0:
480 return 0, u("fichier de configuration RVP non supprimé (ou inexistant)")
481 if del_row == 1:
482 query = """delete from conf_vpn where id_sphynx=%s and id_amon=%s"""
483 params = (int(id_sphynx), int(id_amon))
484 else:
485 nouv_etat=2
486
487 if int(etat) == 0:
488 nouv_etat=3
489 query = """update conf_vpn set etat=%s where id_sphynx=%s and id_amon=%s"""
490 params = (int(nouv_etat), int(id_sphynx), int(id_amon))
491 return self.dbpool.runOperation(query, params).addCallbacks(lambda x : [1,u("OK")],db_client_failed)
492
494 """envoie la configuration RVP d'un amon vers ce sphynx"""
495 try:
496 id_sphynx = int(id_sphynx)
497 id_amon = int(id_amon)
498 sphynx = self.parent.s_pool.get(cred_user,id_sphynx)
499 amon = self.parent.s_pool.get(cred_user,id_amon)
500 except (KeyError, ValueError):
501 return 0, u("serveur inconnu dans la base zephir")
502 try:
503
504 sphynx_dir = sphynx.get_confdir()
505 archive = sphynx_dir + os.sep + 'vpn' + os.sep + str(id_amon) + '.tar.gz'
506 file_conf=open(archive)
507 content=base64.encodestring(file_conf.read())
508 file_conf.close()
509 except:
510 return 0, u("fichier de configuration RVP non trouvé")
511 query = """update conf_vpn set etat=1 where id_sphynx=%s and id_amon=%s"""
512 params = (int(id_sphynx), int(id_amon))
513 return self.dbpool.runOperation(query, params).addCallbacks(lambda x : [1,content],db_client_failed)
514
516 """liste les configs RVP amon présentes pour un sphynx"""
517 cx = PgSQL.connect(database=config.DB_NAME,user=config.DB_USER,password=config.DB_PASSWD)
518 cursor=cx.cursor()
519 query = """select id_amon,etat from conf_vpn where id_sphynx=%s order by etat,id_amon desc""" % id_sphynx
520 cursor.execute(query, (int(id_sphynx),))
521 data=cursor.fetchall()
522 cursor.close()
523 cx.close()
524
525 liste_amons=[]
526 for ligne in data:
527 liste_amons.append([int(ligne[0]),int(ligne[1])])
528 return 1,liste_amons
529
531 """ajoute un fichier de configuration pour réplication d'un annuaire sur seshat (ou autre)"""
532 try:
533 id_serv = int(id_serv)
534 id_client = int(id_client)
535 serv = self.parent.s_pool.get(cred_user,id_serv)
536 client = self.parent.s_pool.get(cred_user,id_client)
537 except (KeyError, ValueError):
538 return 0, u("serveur inconnu dans la base zephir")
539 try:
540 rne = client.parsedico()['numero_etab']
541 assert rne != ""
542 except:
543
544
545 rne = client.rne
546 code, message = serv.add_replication(rne, content, id_client)
547 if code == 0:
548 return code, message
549 else:
550
551
552 return self._update_replication(serv)
553
555 """supprime un fichier de configuration de réplication"""
556 try:
557 id_serv = int(id_serv)
558 serv = self.parent.s_pool.get(cred_user,id_serv)
559 except (KeyError, ValueError):
560 return 0, u("serveur inconnu dans la base zephir")
561 return serv.del_replication(conf_file)
562
564 """prépare l'envoi des configurations de réplication à un serveur central,
565 et demande une regénération de la configuration
566 """
567 try:
568 id_serveur = int(id_serveur)
569 serv = self.parent.s_pool.get(cred_user,id_serveur)
570 except (KeyError, ValueError):
571 return 0, u("serveur inconnu dans la base zephir")
572
573
574 try:
575 self.parent.s_pool.check_replication_infos(id_serveur)
576 except:
577 traceback.print_exc()
578 log.msg('Erreur de mise à jour du fichier etabs.ini')
579 return self._update_replication(serv)
580
582
583 id_uucp = '%s-%s' % (str(serv.get_rne()), str(serv.id_s))
584 code, message = self._send_files(serv, 'replication', ['replication'], uucp=1)
585 if code == 0:
586 return code, u(message)
587 else:
588
589 try:
590 res = uucp_pool.add_cmd(id_uucp, "zephir_client update_replication")
591 except UUCPError, e:
592 return 0, u("Erreur uucp : %s" % str(e))
593 if os.path.isfile(os.path.join(serv.get_confdir(), 'replication', '.modified')):
594 os.unlink(os.path.join(serv.get_confdir(), 'replication', '.modified'))
595 return 1, "OK"
596
598 try:
599 id_serveur = int(id_serveur)
600 serv = self.parent.s_pool.get(cred_user,id_serveur)
601 except (KeyError, ValueError):
602 return 0, u("serveur inconnu dans la base zephir")
603
604 try:
605 self.parent.s_pool.check_replication_infos(id_serveur)
606 except:
607 traceback.print_exc()
608 return 0, u('Erreur de mise à jour du fichier etabs.ini')
609
610 try:
611 data_etab = serv.get_replication_infos()
612 except:
613 return 0, u('Erreur de lecture du fichier etabs.ini')
614 return 1, base64.encodestring(data_etab)
615
616
618 """renvoie l'état de la configuration de réplication LDAP
619 0 : pas de réplication gérée sur ce serveur
620 1 : configurations de réplication en place
621 2 : la configuration doit être renvoyée au serveur (si suppression manuelle de fichiers)
622 """
623 try:
624 id_serveur = int(id_serveur)
625 serv = self.parent.s_pool.get(cred_user,id_serveur)
626 except (KeyError, ValueError):
627 return 0, u("serveur inconnu dans la base zephir")
628 return serv.check_replication()
629
631 """renvoie la liste des configurations de réplication présentes sur un serveur
632 """
633 try:
634 id_serveur = int(id_serveur)
635 serv = self.parent.s_pool.get(cred_user,id_serveur)
636 except (KeyError, ValueError):
637 return 0, u("serveur inconnu dans la base zephir")
638 return serv.get_replication()
639
641 """confirme la réception d'une archive par un serveur"""
642 try:
643 id_serveur = int(id_serveur)
644 serv = self.parent.s_pool.get(cred_user,id_serveur)
645 except (KeyError, ValueError):
646 return 0, u("serveur inconnu dans la base zephir")
647
648 serveur_dir = serv.get_confdir()
649 try:
650
651 os.unlink(serveur_dir+os.sep+archive+'.tar')
652
653 os.unlink(serveur_dir+os.sep+archive+'.md5')
654 except:
655 return 0, u("""erreur de suppression de l'archive""")
656 else:
657 return 1, u('ok')
658
660 """confirme la réception d'une archive par un serveur"""
661 try:
662 id_serveur = int(id_serveur)
663 serv = self.parent.s_pool.get(cred_user,id_serveur)
664 except (KeyError, ValueError):
665 return 0, u("serveur inconnu dans la base zephir")
666
667 serveur_dir = serv.get_confdir()
668
669 try:
670 fic_md5=open(serveur_dir+os.sep+archive+'.md5')
671 md5sum = fic_md5.readlines()
672 fic_md5.close()
673 except:
674 return 0, u("""fichier %s.md5 non trouve""" % (archive))
675 else:
676
677 return 1, base64.encodestring(md5sum[0])
678
680 """installation d'un module (récupération d'un dictionnaire)"""
681
682
683
684 query = """select id, libelle, version from modules where id=%s""" % id_module
685 return self.dbpool.runQuery(query, (int(id_module),)).addCallbacks(self._install_module,db_client_failed,callbackArgs=[dico_b64])
686
688 if data == []:
689 return 0, u("""erreur, module non trouvé""")
690 else:
691 id_module = data[0][0]
692 libelle = data[0][1]
693 version = data[0][2]
694 if version == 1:
695
696 dico_path = os.path.abspath(config.ROOT_DIR)+os.sep+'dictionnaires'
697 dico_b64 = {'dico-'+str(libelle):dico_b64}
698 else:
699
700 dico_path = os.path.abspath(config.ROOT_DIR)+os.sep+'dictionnaires'+os.sep+str(libelle)
701 if not os.path.isdir(dico_path):
702
703 dico_path = os.path.join(os.path.abspath(config.PATH_MODULES),str(id_module),"dicos")
704
705 for dic_name, data in dico_b64.items():
706 dico = os.path.join(dico_path, dic_name)
707 try:
708 if os.path.isfile(dico):
709
710 os.unlink(dico)
711
712 fic_dico = open(dico,'w')
713 fic_dico.write(base64.decodestring(data))
714 fic_dico.close()
715 except:
716 traceback.print_exc()
717 return 0, u("erreur de mise a jour du dictionnaire du module")
718
719 return 1,u("ok")
720
722 """exécution d'un script client sur un serveur/groupe
723 serveurs: id du serveur ou liste d'id
724 script_name: nom du script à exécuter
725 params:paramètres supplémentaires à donner au script
726 """
727 if type(serveurs) != list:
728 serveurs = [serveurs]
729 erreurs = []
730 for id_serveur in serveurs:
731 try:
732 id_serveur = int(id_serveur)
733 serv = self.parent.s_pool.get(cred_user, id_serveur)
734 except:
735 erreurs.append("Serveur %s : inexistant ou accès refusé" % str(id_serveur))
736 continue
737 try:
738 id_uucp = str(serv.get_rne()) + '-' + str(serv.id_s)
739 cmd = "zephir_client %s %s" % (script_name, params)
740 uucp_pool.add_cmd(id_uucp,cmd.strip())
741 except UUCPError,e:
742 erreurs.append("serveur %s (%s) : Erreur UUCP %s" % (serv.id_s, serv.rne, str(e)))
743 continue
744 if len(erreurs) == len(serveurs):
745 return 0, "Echec de l'exécution ou action interdite sur tous les serveurs"
746 return 1, erreurs
747
749 """sauvegarde des fichiers de configuration d'un serveur"""
750 try:
751 id_serveur = int(id_serveur)
752 serv = self.parent.s_pool.get(cred_user, id_serveur)
753 except (KeyError, ValueError):
754 return 0, u("serveur inconnu dans la base zephir")
755 module = serv.id_mod
756 variante = serv.id_var
757 archive='fichiers_zephir'+str(id_serveur)
758 public_dir = '/var/spool/uucppublic'
759 temp_dir = public_dir+os.sep+str(id_serveur)
760
761
762 if os.path.isdir(temp_dir):
763 shutil.rmtree(temp_dir)
764 try:
765 os.mkdir(temp_dir)
766 except:
767 return 0, u("""erreur de creation du repertoire temporaire""")
768 serveur_dir = serv.get_confdir()
769
770 try:
771 fic_md5 = open(public_dir+os.sep+archive+'.md5','w')
772 fic_md5.write(checksum)
773 fic_md5.close()
774 except:
775 return 0, u("""erreur d'écriture du fichier de checksum""")
776 cmd_md5 = """cd %s ; md5sum -c %s.md5 2>&1 > /dev/null""" % (public_dir,archive)
777 res=os.system(cmd_md5)
778 if res != 0:
779 return 0, u("""archive corrompue""")
780 else:
781
782 cmd_tar = """cd %s ; tar -C %s --same-owner -xhpf %s.tar >/dev/null 2>&1""" % (public_dir,str(id_serveur),archive)
783 os.system(cmd_tar)
784
785
786 directories = ['dicos','fichiers_perso','patchs','fichiers_zephir']
787 for rep in directories:
788 if os.path.exists(os.path.join(temp_dir, 'temp_zephir', rep)):
789 try:
790 if rep == 'dicos' and os.path.isdir(os.path.join(os.path.abspath(config.PATH_MODULES),str(module),'dicos')):
791
792 shutil.rmtree(serveur_dir+os.sep+rep+'/local')
793 else:
794 shutil.rmtree(serveur_dir+os.sep+rep)
795 except:
796
797 pass
798
799 res = 0
800 for rep in directories:
801 if res == 0:
802 if os.path.exists(os.path.join(temp_dir, 'temp_zephir', rep)):
803 if os.path.isdir(os.path.join(os.path.abspath(config.PATH_MODULES),str(module),'dicos')) and rep == 'dicos':
804
805 res = os.system("mv -f %s %s" % (temp_dir+'/temp_zephir/'+rep+'/local', os.path.join(serveur_dir,rep)))
806 else:
807 res = os.system("mv -f %s %s" % (temp_dir+'/temp_zephir/'+rep,serveur_dir))
808 if res == 0:
809 res = os.system('ln -s '+os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+'/variantes/'+str(variante)+os.sep+rep+' '+serveur_dir+os.sep+rep+os.sep+'variante')
810
811 if res != 0:
812 return 0, u("""erreur de mise en place des fichiers""")
813
814 if os.path.exists(os.path.join(temp_dir, 'temp_zephir', 'zephir.eol')):
815
816 res = os.system("mv -f %s %s" % (temp_dir+'/temp_zephir/zephir.eol',serveur_dir))
817 if res != 0:
818 return 0, u("""erreur de mise en place de zephir.eol""")
819 else:
820
821 serv.maj_params({'config_ok':1})
822
823 if serv.dico is not None:
824 if config.CREOLE_CACHE:
825 serv.dico.mode = None
826 serv.load_conf('modif_config')
827 else:
828 serv.last_mode = None
829 serv.get_config('modif_config')
830
831
832 new_method = serv.check_min_version(self.parent.maj_checker, 'zephir-client', '2.3-eole54~1')
833 serv.check_md5conf(new_method)
834
835 try:
836
837 os.unlink(public_dir+os.sep+archive+'.tar')
838 os.unlink(public_dir+os.sep+archive+'.md5')
839 shutil.rmtree(temp_dir)
840 except:
841 return 0, u("""erreur de supression des fichiers temporaires""")
842 return 1, u('ok')
843
844
846 """installation d'une variante pour un module"""
847 try:
848 id_serveur = int(id_serveur)
849 serv = self.parent.s_pool.get(cred_user, id_serveur)
850 except (KeyError, ValueError):
851 return 0, u("serveur inconnu dans la base zephir")
852 module = serv.id_mod
853 variante = serv.id_var
854 query = """select id,module,owner,passmd5 from variantes where id = %s and module = %s"""
855 params = (int(variante), int(module))
856 return self.dbpool.runQuery(query, params).addCallbacks(self._install_variante2,db_client_failed,callbackArgs=[cred_user,checksum,login,passwd_md5,serv.get_rne(),id_serveur])
857
858
860 """vérification de l'archive et stockage des fichiers"""
861 if data == []:
862 return 0, u("""variante non retrouvée dans la base""")
863 variante = data[0][0]
864 module = data[0][1]
865 owner_var = data[0][2]
866 passwd_var= data[0][3]
867 archive='variante'+str(id_serveur)
868 public_dir = '/var/spool/uucppublic'
869 temp_dir = public_dir+os.sep+str(id_serveur)
870 variante_dir = os.path.abspath(config.PATH_ZEPHIR)+os.sep+'modules'+os.sep+str(module)+os.sep+'variantes'+os.sep+str(variante)
871
872
873 if cred_user != owner_var:
874
875 if passwd_var not in [None,'']:
876
877 if passwd_md5 != passwd_var:
878 return 0, u("""erreur, le mot de passe est invalide""")
879
880
881
882 if os.path.isdir(temp_dir):
883 shutil.rmtree(temp_dir)
884 try:
885 os.mkdir(temp_dir)
886 except:
887 return 0, u("""erreur de création du repertoire temporaire""")
888
889 try:
890 fic_md5 = open(public_dir+os.sep+archive+'.md5','w')
891 fic_md5.write(checksum)
892 fic_md5.close()
893 except:
894 return 0, u("""erreur d'écriture du fichier de checksum""")
895 cmd_md5 = """cd %s ; md5sum -c %s.md5 2>&1 > /dev/null""" % (public_dir,archive)
896 res=os.system(cmd_md5)
897 if res != 0:
898 return 0, u("""archive corrompue""")
899 else:
900
901 cmd_tar = """cd %s ; tar -C %s --same-owner -xhpf %s.tar > /dev/null""" % (public_dir,str(id_serveur),archive)
902 os.system(cmd_tar)
903
904
905 try:
906 shutil.rmtree(variante_dir+os.sep+'dicos')
907 shutil.rmtree(variante_dir+os.sep+'patchs')
908 shutil.rmtree(variante_dir+os.sep+'fichiers_perso')
909 shutil.rmtree(variante_dir+os.sep+'fichiers_zephir')
910 except:
911 return 0, u("""erreur de supression de l'ancienne variante""")
912
913 res = os.system("mv %s %s" % (temp_dir+os.sep+'patch/variante',variante_dir+os.sep+'patchs'))
914 if res == 0:
915 res = os.system("mv %s %s" % (temp_dir+os.sep+'dicos/variante',variante_dir+os.sep+'dicos'))
916 if res == 0:
917 res = os.system("mv %s %s" % (temp_dir+os.sep+'fichiers_perso',variante_dir+os.sep+'fichiers_perso'))
918 if res == 0:
919 res = os.system("mv %s %s" % (temp_dir+os.sep+'fichiers_zephir',variante_dir+os.sep+'fichiers_zephir'))
920 if res != 0:
921 return 0, u("""erreur de mise en place de la variante""")
922
923 try:
924
925 os.unlink(public_dir+os.sep+archive+'.tar')
926 os.unlink(public_dir+os.sep+archive+'.md5')
927 shutil.rmtree(temp_dir)
928 except:
929 return 0, u("""erreur de supression des fichiers temporaires""")
930
931 if passwd_var in [None,'']:
932
933 query = """update variantes set owner=%s, passmd5=%s where id = %s and module = %s"""
934 params = (login, passwd_md5, int(variante), int(module))
935 return self.dbpool.runOperation(query, params).addCallbacks(lambda x : [1,'ok'],lambda x : [0,'erreur de stockage du mot de passe'])
936 else:
937 return 1,u('ok')
938
940 """ met à jour la table d'état du serveur pour une action précise
941 (ex: MAJ ou CONFIG) afin de refléter l'état de cohérence actuelle du serveur
942 """
943 params = {'last_log':str(date)}
944 if type_action in ['MAJ','CONFIGURE','RECONFIGURE','SAUVEGARDE','REBOOT','SERVICE_RESTART','UPGRADE','PERSO']:
945
946 if int(etat) == -1:
947 params['%s_ok' % type_action.lower()] = [2, str(date), msg]
948 elif int(etat) > 0:
949 params['%s_ok' % type_action.lower()] = [0, str(date), msg]
950 elif int(etat) == 0:
951 if type_action == "MAJ":
952
953
954 pass
955 elif type_action == "CONFIGURE":
956
957
958
959 md5file = os.path.join(os.path.abspath(config.PATH_ZEPHIR),'data','config%s.md5' % id_serveur)
960 if os.path.isfile(md5file):
961 self.parent.s_pool.edit_serveur(id_serveur,{'md5s':1})
962 params['md5s'] = [1,""]
963 params['%s_ok' % type_action.lower()] = [1, str(date), msg]
964 elif type_action == 'LOCK':
965 if int(etat) == 1:
966 params['lock_ok'] = [2, str(date), msg]
967 else:
968 params['lock_ok'] = [1,'']
969 try:
970 id_serveur = int(id_serveur)
971 serv = self.parent.s_pool[id_serveur]
972 if serv.version == 'creole1':
973 if params.has_key('query_maj'):
974 params['query_maj'] = [-2,""]
975 except (KeyError, ValueError):
976 return 0, u("serveur inconnu dans la base zephir")
977 else:
978
979 self.parent.s_pool.update_contact(id_serveur)
980
981
982 query = """select id,etat,date,type from last_log_serveur where id_serveur=%s and type=%s"""
983 sql_params = (int(id_serveur), type_action)
984 return self.dbpool.runQuery(query, sql_params).addCallbacks(self._log_serveur,db_client_failed,callbackArgs=[id_serveur,type_action,date,int(etat),msg, params, serv])
985
986 - def _log_serveur(self,data,id_serveur,type_action,date,etat,msg,params,serv):
987
988 if data != []:
989
990 last_date = data[0][2]
991 try:
992 new_date = datetime.strptime(str(date), "%c")
993 except:
994 try:
995
996
997 new_date = str(date).split()
998 new_date[0] = config.days[new_date[0]]
999 new_date[1] = config.months[new_date[1]]
1000 new_date = " ".join(new_date)
1001 new_date = datetime.strptime(str(new_date),"%a %b %d %H:%M:%S %Y")
1002 except:
1003 log.msg("Serveur %s - erreur de lecture de la date pour le log suivant : %s, %s, %s (%s)" % \
1004 (str(id_serveur), type_action, str(etat), msg, date))
1005 log.msg("utilisation de la date courante pour ce log")
1006 new_date = datetime.utcnow()
1007 if new_date >= last_date:
1008 query = """update last_log_serveur set id_serveur=%s,date=%s,type=%s,message=%s,etat=%s where id=%s"""
1009 sql_params = (int(id_serveur), date, type_action, msg, int(etat), int(data[0][0]))
1010
1011
1012
1013 serv.maj_params(params)
1014 else:
1015
1016 return self._log_serveur2(None,id_serveur,type_action,date,etat,msg)
1017 else:
1018 query = """insert into last_log_serveur (id_serveur,date,type,message,etat) values (%s,%s,%s,%s,%s)"""
1019 sql_params = (int(id_serveur), date, type_action, msg, int(etat))
1020
1021
1022
1023 serv.maj_params(params)
1024 return self.dbpool.runOperation(query, sql_params).addCallbacks(self._log_serveur2,db_client_failed,callbackArgs=[id_serveur,type_action,date,etat,msg])
1025
1026 - def _log_serveur2(self,data,id_serveur,type_action,date,etat,msg):
1027 query = """insert into log_serveur (id_serveur,date,type,message,etat) values (%s,%s,%s,%s,%s)"""
1028 sql_params = (int(id_serveur), date, type_action, msg, etat)
1029
1030 return self.dbpool.runOperation(query, sql_params).addCallbacks(lambda x : [1,'ok'],db_client_failed)
1031
1033 """prépare la suppression des verrous sur un groupe"""
1034 erreurs=[]
1035 for serveur in liste:
1036 retour = self.xmlrpc_release_lock(cred_user, serveur['id'])
1037 if retour[0] == 0:
1038 erreurs.append(str(serveur['id'])+' : '+retour[1])
1039 if erreurs != []:
1040 return 0, u(erreurs)
1041 else:
1042 return 1, u('ok')
1043
1045 """demande la libération des verrous sur un serveur"""
1046 try:
1047 id_serveur = int(id_serveur)
1048 serv = self.parent.s_pool.get(cred_user,id_serveur)
1049 except (KeyError, ValueError):
1050 return 0, u("serveur inconnu dans la base zephir")
1051 else:
1052 serv.maj_params({'del_locks':True})
1053 return 1, 'ok'
1054
1056 """indique si les locks doivent être ignorés
1057 @params unlocked: si True, on enlève l'attibut del_lock de params"""
1058 try:
1059 id_serveur = int(id_serveur)
1060 serv = self.parent.s_pool.get(cred_user,id_serveur)
1061 except (KeyError, ValueError):
1062 return 0, u("serveur inconnu dans la base zephir")
1063 params = serv.get_params()
1064 if params.has_key('del_locks'):
1065 if params['del_locks'] == True:
1066 if unlocked:
1067
1068 serv.maj_params({'del_locks':False})
1069
1070 return 1, True
1071 return 1, False
1072
1074 """envoi d'un message d'alerte à une liste d'adresses mail
1075 """
1076 bad_addr={}
1077 mail = email.MIMEText.MIMEText(msg)
1078 mail['Subject'] = Header("[Zephir] %s" % subject,"utf-8")
1079 mail['From'] = Header(config.MAIL_ACCOUNT, "utf-8")
1080 mail.set_charset('UTF-8')
1081 mail_client=smtplib.SMTP()
1082 orig_timeout = smtplib.socket.getdefaulttimeout()
1083 try:
1084 smtplib.socket.setdefaulttimeout(3)
1085 if config.MAIL_TLS.startswith('port '):
1086 mail_client.connect(config.MAIL_ADRESSE,int(config.MAIL_TLS.replace('port ','')))
1087 else:
1088 mail_client.connect(config.MAIL_ADRESSE)
1089 smtplib.socket.setdefaulttimeout(orig_timeout)
1090 except:
1091 smtplib.socket.setdefaulttimeout(orig_timeout)
1092 return 0, u('erreur de connexion au serveur smtp')
1093 else:
1094 try:
1095 mail_client.ehlo_or_helo_if_needed()
1096 if config.MAIL_TLS.startswith('port '):
1097 try:
1098 mail_client.starttls()
1099 except smtplib.SMTPException, e:
1100 return 0, u("Erreur d'envoi du mail d'alerte : le serveur %s ne gère pas les connexions cryptées (TLS)" % config.MAIL_ADRESSE)
1101 bad_addr = mail_client.sendmail(config.MAIL_ACCOUNT,adresses,mail.as_string())
1102 except:
1103 return 0, u("erreur d'envoi du mail d'alerte")
1104 return 1, bad_addr
1105
1106 - def xmlrpc_maj_site(self,cred_user,ip_publique,id_serveur,checksum,new_agents=0):
1107 if config.USE_THREADS:
1108 return threads.deferToThread(self._maj_site, cred_user,ip_publique, \
1109 id_serveur,checksum,new_agents)
1110 else:
1111 return self._maj_site(cred_user, ip_publique, id_serveur, checksum, new_agents)
1112
1113 - def _maj_site(self,cred_user,ip_publique,id_serveur,checksum,new_agents=0):
1114 """vérifie l'archive envoyée par le serveur et met le site et les données xml en place
1115 """
1116 log.msg ("connexion du serveur %s" % str(id_serveur))
1117
1118 cx = PgSQL.connect(database=config.DB_NAME,user=config.DB_USER,password=config.DB_PASSWD)
1119 query="""select type,etat from last_log_serveur where id_serveur=%s and type='LOCK' order by date desc, id desc"""
1120 cursor=cx.cursor()
1121 cursor.execute(query, (int(id_serveur),))
1122 data=cursor.fetchall()
1123 cursor.close()
1124 cx.close()
1125 etat=0
1126 if data != []:
1127 etat=int(data[0][1])
1128 if etat == 1:
1129
1130 self.xmlrpc_log_serveur(cred_user,id_serveur,str(time.ctime()),'LOCK','0',"""Reprise de l'activité uucp""")
1131
1132 self.parent.s_pool.update_contact(id_serveur)
1133
1134 public_dir = '/var/spool/uucppublic'
1135 archive = 'site%s' % id_serveur
1136 try:
1137 fic_md5 = open(public_dir+os.sep+archive+'.md5','w')
1138 fic_md5.writelines(checksum)
1139 fic_md5.close()
1140 except:
1141 return 0, u("""erreur d'écriture du fichier de checksum""")
1142 cmd_md5 = """cd %s ; md5sum -c %s.md5 2>&1 > /dev/null""" % (public_dir, archive)
1143 res=os.system(cmd_md5)
1144 if res != 0:
1145 return 0, u("""archive corrompue""")
1146 else:
1147 compressed=''
1148
1149 if int(new_agents) == 1:
1150
1151 compressed = 'z'
1152 rep_dest = os.path.abspath(config.PATH_ZEPHIR)
1153
1154 try:
1155 shutil.rmtree(rep_dest+os.sep+"data"+os.sep+str(id_serveur))
1156 except:
1157 pass
1158 else:
1159 rep_dest = os.path.abspath(config.PATH_ZEPHIR)+os.sep+"sites"+os.sep+str(id_serveur)
1160
1161 if os.path.exists(rep_dest):
1162 shutil.rmtree(rep_dest)
1163 os.makedirs(rep_dest)
1164
1165 cmd_tar = """cd %s ; /bin/tar -C %s -x%sf %s.tar 2> /dev/null""" % (public_dir, rep_dest, compressed, archive)
1166 res=os.system(cmd_tar)
1167 if res != 0:
1168 return 0, u("erreur de mise en place du site sur zephir")
1169 serv = self.parent.s_pool[int(id_serveur)]
1170 if self.parent.maj_checker:
1171 serv.check_maj_status(self.parent.maj_checker)
1172 new_method = serv.check_min_version(self.parent.maj_checker, 'zephir-client', '2.3-eole54~1')
1173
1174 serv.check_md5conf(new_method)
1175 serv.update_ip_pub(ip_publique)
1176 if int(new_agents) == 1 and serv.version == 'creole1':
1177
1178 f_site = file(os.path.join(rep_dest,'data',str(id_serveur),'site.cfg'))
1179 data = f_site.read()
1180 f_site.close()
1181 try:
1182 data = unicode(data,'ISO-8859-1').encode(config.charset)
1183 except:
1184 pass
1185 else:
1186 f_site = file(os.path.join(rep_dest,'data',str(id_serveur),'site.cfg'),'w')
1187 f_site.write(data)
1188 f_site.close()
1189 for xml_file in glob.glob(os.path.join(rep_dest,'data',str(id_serveur),'*/agent.xml')):
1190 try:
1191 xml = file(xml_file).read()
1192
1193 for ori, dst in config.xml_table.items():
1194 xml = xml.replace(ori,dst)
1195 file(xml_file,'w').write(xml)
1196 except:
1197 log.msg("erreur lors de la conversion de %s en %s" % (xml_file, config.charset))
1198
1199
1200 list_errors = []
1201 try:
1202 if self.agent_manager.has_key(str(id_serveur)):
1203
1204
1205 self.agent_manager[str(id_serveur)].update_structure()
1206 stats = self.agent_manager[str(id_serveur)].get_measure()
1207 result_ag = self.agent_manager[str(id_serveur)].global_status()
1208 if result_ag == 0:
1209
1210 liste_errors = []
1211 for ag_name, detail_ag in self.agent_manager[str(id_serveur)].agents_status().items():
1212 if detail_ag[1] == 0 and ag_name != 'tcpservices':
1213 list_errors.append(detail_ag[0])
1214 else:
1215
1216
1217 AgentCollecteur(id_serveur)
1218 result_ag = ServeurStatus(id_serveur).get_status()
1219 except:
1220 traceback.print_exc()
1221 result_ag = 1
1222
1223
1224 try:
1225 result_zeph = self.parent.getSubHandler('serveurs').xmlrpc_get_status(cred_user,id_serveur)
1226 except:
1227 return 0, u("erreur de récupération de l'état zephir du serveur %s" % id_serveur)
1228
1229 d = defer.Deferred()
1230 d.addCallback(self._alerte,result_zeph[1],result_ag,list_errors)
1231 d.callback(id_serveur)
1232
1233 return 1,u("ok")
1234
1235
1236 - def _alerte(self,id_serveur,etat_zeph,etat_ag,list_errors):
1237 """vérification de l'état du serveur et envoi mail si nécessaire
1238 """
1239
1240 query="select serveurs.id,serveurs.rne,installateur,serveurs.libelle, \
1241 modules.libelle,etablissements.libelle,serveurs.etat \
1242 from serveurs,etablissements,modules \
1243 where serveurs.id=%s and etablissements.rne=serveurs.rne and modules.id=module_actuel"
1244 self.dbpool.runQuery(query, (int(id_serveur),)).addCallbacks(self._alerte2,db_client_failed,callbackArgs=[etat_zeph,etat_ag,list_errors])
1245
1246 - def _alerte2(self,data,etat_zeph,etat_ag,list_errors):
1247
1248 if data == []:
1249
1250 pass
1251 else:
1252 id_serveur = data[0][0]
1253 rne = data[0][1]
1254 libelle = data[0][3]
1255 module = data[0][4]
1256 libel_etab = data[0][5]
1257 etat_precedent = data[0][6]
1258 if etat_precedent != None:
1259 try:
1260 etat_precedent = int(etat_precedent)
1261 except Exception, e:
1262 etat_precedent = 1
1263 erreur = 0
1264 msg = """le serveur %s (%s - %s)\n établissement : %s (%s)""" % (libelle, id_serveur, module, rne, libel_etab)
1265
1266 for cle in etat_zeph.keys():
1267 etat = etat_zeph[cle]
1268 if type(etat) == list:
1269 if len(etat) == 3:
1270 if etat[0] == 0:
1271 if erreur == 0:
1272 msg += """\n(se reporter à la page d'état du serveur dans l'application web)"""
1273 erreur = 1
1274 msg +="""\n\nlog du %s : %s""" % (etat[1].encode(config.charset),etat[2].encode(config.charset))
1275 if (cle == 'lock_ok') and (etat[0] != 1):
1276 msg += """\n\n Fonction Zephir verrouillées, connectez vous sur le serveur pour vérifier son état
1277 (commande '/usr/share/zephir/scripts/zephir_client del_lock' pour déverrouiller)"""
1278
1279
1280 serv = self.parent.s_pool[id_serveur]
1281 serv.maj_params({'agents':etat_ag})
1282 if etat_ag == 0:
1283 erreur = 2
1284
1285 msg += """\n\nerreur remontée par le serveur (cf. https://%s:%s/agents/%s)""" % (config.ADRESSE_ZEPHIR,config.PORT_HTTP,id_serveur)
1286 if list_errors != []:
1287 msg += """\n\n* %s""" % "\n* ".join(list_errors)
1288
1289
1290
1291 if erreur != 0:
1292 if etat_precedent not in [0,4]:
1293 if etat_precedent == 3:
1294 serv.set_status(4)
1295 else:
1296 serv.set_status(0)
1297 if serv.no_alert == False:
1298
1299 if etat_precedent == 2:
1300
1301 subject = "problème détecté à la reprise de contact: serveur %s (%s)" % (libelle,rne)
1302 else:
1303 subject = "problème détecté : serveur %s (%s)" % (libelle,rne)
1304 msg = "\nproblème détecté sur " + msg
1305 self._send_alerte("problème détecté : serveur ",{int(id_serveur):msg})
1306 else:
1307
1308
1309 if etat_precedent in [0,4]:
1310 if etat_precedent == 4:
1311 serv.set_status(3)
1312 else:
1313 serv.set_status(1)
1314 if serv.no_alert == False:
1315
1316 subject = "fin d'alerte : serveur %s (%s)" % (libelle,rne)
1317 msg = "\n fin d'alerte pour " + msg
1318 self._send_alerte("fin d'alerte : ",{int(id_serveur):msg})
1319
1320 if etat_precedent == None:
1321 serv.set_status(1)
1322
1324 """recherche les mails et sms des personnes surveillant un serveur particulier
1325 """
1326 if msgs != {}:
1327 query = """select id,serveurs from groupes_serveurs"""
1328 self.dbpool.runQuery(query).addCallbacks(self._send_alerte2,db_client_failed,callbackArgs=[subject,msgs])
1329
1331
1332
1333 groupes=[]
1334 for id_serveur in msg.keys():
1335 for groupe in data:
1336 if id_serveur in eval(groupe[1]):
1337 if groupe[0] not in groupes:
1338 groupes.append(groupe[0])
1339 query = """select groupes,mail,sms,mail_actif,sms_actif from users \
1340 where groupes != '' and (mail_actif=1 or sms_actif=1)"""
1341 self.dbpool.runQuery(query).addCallbacks(self._send_alerte3,db_client_failed,callbackArgs=[groupes,subject,msg])
1342
1344 """regarde quels utilisateurs surveillent les groupes
1345 en question et envoie un mail ou sms si besoin
1346 """
1347
1348 destinataires = []
1349 for user in data:
1350 try:
1351 groupes_user=eval(user[0])
1352 except:
1353 groupes_user=[]
1354 for groupe in groupes_user:
1355
1356 if groupe in groupes:
1357
1358 if user[3]==1:
1359
1360 for adresse in user[1].split(','):
1361 r=re.match("""^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9]+)*$""",adresse)
1362 if r is not None:
1363
1364 if adresse not in destinataires:
1365 destinataires.append(adresse)
1366
1367 if destinataires != []:
1368 self._sendmail(destinataires,subject + str(msg.keys()),"\n".join(msg.values()))
1369
1371 """vérifie toutes les x minutes si des serveurs ont dépassé leur timeout.
1372 vérification toutes les 5 miuntes par défaut"""
1373
1374 try:
1375
1376 if self.start_time is not None:
1377
1378
1379 self.parent.maj_checker = AptChecker()
1380 query = "update serveurs set last_contact=%s where last_contact is not null and etat <> 2"
1381 self.dbpool.runOperation(query, (self.start_time,)).addCallbacks(lambda x : [1, "OK"],db_client_failed)
1382 reactor.callLater(5, self._scan_timeouts)
1383 except:
1384 traceback.print_exc()
1385 return 0, "erreur de démarrage de la boucle de surveillance"
1386 return 1,""
1387
1389 reactor.callLater(self.scan_delay, self._scan_timeouts)
1390 if config.LOG_ACTIONS:
1391 log.msg('Recherche des pertes de contact')
1392 query = """select serveurs.id,timeout,last_contact,serveurs.libelle, \
1393 serveurs.rne,etablissements.libelle,modules.libelle,serveurs.etat \
1394 from serveurs,etablissements,modules where timeout > 0 and last_contact is not null and \
1395 serveurs.rne=etablissements.rne and module_actuel=modules.id"""
1396 self.dbpool.runQuery(query).addCallbacks(self._scan_timeouts2,db_client_failed)
1397
1399 """vérifie si le dernier contact est moins ancien que le timeout du serveur.
1400 """
1401
1402 if self.start_time is not None and config.CREOLE_CACHE:
1403 self.start_time = None
1404 reactor.callInThread(self.update_creole, [serv[0] for serv in data])
1405
1406 cmds=uucp_pool._scan_pool()
1407 d_list = []
1408 for serveur in data:
1409
1410 if config.USE_THREADS:
1411 def_check = threads.deferToThread(self.check_timeout, serveur)
1412 else:
1413 def_check = defer.maybeDeferred(self.check_timeout, serveur)
1414 d_list.append(def_check)
1415 d = defer.DeferredList(d_list, consumeErrors=True)
1416 d.addCallback(self._send_alertes)
1417
1419 erreurs={}
1420 reprises={}
1421 bloquages={}
1422 debloquages={}
1423
1424 for success, data in results:
1425 if success:
1426 erreurs.update(data[0])
1427 reprises.update(data[1])
1428 bloquages.update(data[2])
1429 debloquages.update(data[3])
1430 else:
1431 log.msg("! Erreur lors de la vérification du timeout d'un serveur : %s" \
1432 % str(data.getErrorMessage()))
1433 self._send_alerte("commandes non lancées : ",bloquages)
1434 self._send_alerte("commandes débloquées : ",debloquages)
1435 self._send_alerte("perte de contact : ",erreurs)
1436 self._send_alerte("reprise du contact : ",reprises)
1437
1439 """vérifie si un serveur a dépassé le délai de connexion autorisé
1440 """
1441 erreurs={}
1442 reprises={}
1443 bloquages={}
1444 debloquages={}
1445
1446 serv = self.parent.s_pool[int(serveur[0])]
1447 params = {'timeout':[-2, ""]}
1448 last = float(serveur[2])
1449 delta = float(time.time()) - last
1450 try:
1451 etat_actuel = int(serveur[7])
1452 except:
1453 etat_actuel = 1
1454
1455 try:
1456 timeout = int(serveur[1])
1457 except:
1458 pass
1459 else:
1460 params['timeout'] = [1, time.ctime(last)]
1461
1462
1463 max_delay = int(timeout) * 2 + 240
1464 if ( delta > max_delay ) and timeout != 0:
1465 params['timeout'][0]=0
1466 if etat_actuel != 2:
1467
1468 reactor.callFromThread(log.msg, "timeout du serveur %s" % serveur[0])
1469 serv.set_status(2)
1470
1471 if serv.no_alert == False:
1472 subject = """perte du contact : serveur(s) %s (%s)""" % (serveur[3],serveur[4])
1473 msg="""Dernier contact avec le serveur n°%s - %s (%s) de l'établissement %s (%s) : %s""" % (serveur[0],serveur[3],serveur[6],serveur[4],serveur[5],time.ctime(last))
1474
1475 erreurs[serveur[0]]=msg
1476 else:
1477 if etat_actuel == 2:
1478
1479 serv.set_status(1)
1480 if serv.no_alert == False and timeout != 0:
1481 subject = """reprise du contact : serveur(s) %s (%s)""" % (serveur[3],serveur[4])
1482 msg = """reprise du contact avec le serveur n°%s - %s (%s) de l'établissement %s (%s) : %s""" % \
1483 (serveur[0],serveur[3],serveur[6],serveur[4],serveur[5],time.ctime(last))
1484 reprises[serveur[0]]=msg
1485
1486
1487 id_uucp = serveur[4]+"-"+str(serveur[0])
1488 old_cmds = uucp_pool.check_timeout(max_delay, id_uucp)
1489 if old_cmds != {} and timeout != 0:
1490 if etat_actuel not in [3,4]:
1491
1492 if serv.no_alert == False:
1493 msg = """commandes bloquées en attente pour le serveur n°%s - %s (%s) de l'établissement %s (%s)
1494 Vous pouvez afficher les logs de transfert UUCP sur ce serveur à l'aide de la commande uulog"""
1495 bloquages[serveur[0]] = msg % (serveur[0],serveur[3],serveur[6],serveur[4],serveur[5])
1496 if etat_actuel == 0:
1497
1498 serv.set_status(4)
1499 else:
1500
1501 serv.set_status(3)
1502 elif etat_actuel in [3,4]:
1503
1504 if serv.no_alert == False and timeout != 0:
1505 msg = """débloquage des commandes (reprise d'activité uucp) pour le serveur n°%s - %s (%s) de l'établissement %s (%s)"""
1506 debloquages[serveur[0]] = msg % (serveur[0],serveur[3],serveur[6],serveur[4],serveur[5])
1507 if etat_actuel == 4:
1508
1509 serv.set_status(0)
1510 else:
1511
1512 serv.set_status(1)
1513
1514
1515 serv.maj_params(params)
1516 return erreurs, reprises, bloquages, debloquages
1517
1519
1520 log.msg("Début de mise en cache des configurations des serveurs")
1521 max_serv = len(serveurs)
1522 for num_serv, serveur in enumerate(serveurs):
1523 if not reactor.running:
1524
1525
1526 break
1527
1528 def_upd = defer.Deferred()
1529 def_upd.addCallback(self._update_creole, max_serv, num_serv)
1530 def_upd.callback(serveur)
1531 log.msg("Fin de mise en cache des configurations")
1532
1534 id_serv = int(serveur)
1535 try:
1536 serv = self.parent.s_pool[id_serv]
1537
1538
1539 if self.parent.dictpool.check_module(serv.id_mod):
1540 self.parent.dictpool.check_dirs(serv)
1541 if serv.dico is None:
1542 serv.get_config('modif_config')
1543 if divmod(current, 50)[1] == 0 and current != 0:
1544
1545 log.msg("Mise en cache des configurations : %d/%d effectué" % (current, nb_serv))
1546 except Exception, e:
1547 log.msg("Erreur de lecture de la configuration du serveur %s (%s)" % (str(id_serv), str(e)))
1548
1550 """retourne la liste des actions uucp en attente"""
1551
1552 try:
1553 id_serveur = int(id_serveur)
1554 serv = self.parent.s_pool.get(cred_user, id_serveur)
1555 except (KeyError, ValueError):
1556 return 0, u("serveur inconnu dans la base zephir")
1557 else:
1558 id_uucp = str(serv.get_rne()) + '-' + str(id_serveur)
1559
1560 try:
1561 cmds=uucp_pool.list_cmd(id_uucp)[id_uucp]
1562 except:
1563 cmds={}
1564 try:
1565 files=uucp_pool.list_files(id_uucp)[id_uucp]
1566 except:
1567 files={}
1568 return 1,u([cmds,files])
1569
1571 """indique à un serveur si il doit ou non effectuer des actions
1572 """
1573
1574 try:
1575 id_serveur = int(id_serveur)
1576 serv = self.parent.s_pool.get(cred_user, id_serveur)
1577 except (KeyError, ValueError):
1578 return 0, u("serveur inconnu dans la base zephir")
1579 else:
1580 id_uucp = str(serv.get_rne()) + '-' + str(id_serveur)
1581
1582 cmds=uucp_pool._scan_pool()
1583 if len(uucp_pool.pool[id_uucp]) > 0:
1584 return 1, True
1585 else:
1586 return 1, False
1587
1589 """annule toutes les actions en attente sur un/plusieurs serveur(s)"""
1590
1591 try:
1592 for id_serveur in serveurs:
1593 id_serveur = int(id_serveur)
1594 assert self.parent.s_pool.has_key(id_serveur)
1595 except (KeyError, ValueError):
1596 return 0, u("serveur inconnu dans la base zephir")
1597 else:
1598 for id_serveur in serveurs:
1599 rne = self.parent.s_pool.get(cred_user,int(id_serveur)).get_rne()
1600 id_uucp = str(rne) + '-' + str(id_serveur)
1601
1602 if id_tache is None:
1603 try:
1604 uucp_pool.flush([id_uucp])
1605 except UUCPError, e:
1606 return 0, u("erreur de purge des commandes : %" % str(e))
1607 else:
1608 try:
1609 uucp_pool.remove_cmd(id_uucp,int(id_tache))
1610 except UUCPError, e:
1611 return 0, u("Erreur de supression de la commande uucp : %" %str(e))
1612 except KeyError:
1613 pass
1614
1615 return 1,"OK"
1616