1
2
3
4
5
6
7
8
9
10
11
12
13 """module de gestion des modules Eole
14 """
15 from twisted.python import log
16 from twisted.internet import reactor
17 from zephir.backend.db_utils import *
18 from zephir.backend import config
19 from zephir.backend.config import u
20 from zephir.backend.xmlrpceole import XMLRPCEole as XMLRPC
21 from zephir.backend.lib_backend import ResourceAuthError, istextfile, cx_pool
22 from zephir.utils.creolewrap import ZephirDict
23
24
25 from twisted.enterprise import adbapi
26 import sys,os,shutil,md5,time,dico,base64,ConfigParser
27 from zephir.eolerpclib import xmlrpclib
28 from creole.cfgparser import EoleDict, eosfunc
29
31 """serveur XMLRPC zephir pour la gestion des modules Eole
32 """
33
34 - def __init__(self,parent,bdd='zephir-parc'):
35 self.dbpool = db_connect()
36 self.dbpool.noisy = 0
37 self.parent = parent
38
39 XMLRPC.__init__(self)
40
42 """vérification de la liste des modules"""
43 cursor = cx_pool.create()
44 try:
45 cursor.execute("""select libelle from modules""")
46 modules_actuels = [module[0] for module in cursor.fetchall()]
47 except:
48 cx_pool.close(cursor)
49
50 print "\nErreur de lecture de la liste des modules\n"
51 return 0, u("Erreur de lecture de la liste des modules")
52 cx_pool.close(cursor)
53 new_modules = []
54 for module in config.liste_modules:
55 if module not in modules_actuels:
56 if module in config.OLD_MODULES:
57 version = 1
58 else:
59 version = 2
60
61 try:
62 new_modules.append(module)
63 self.xmlrpc_add_module("", module, version)
64 except:
65 return 0, u("erreur d'ajout du module %s" % module)
66
67 if len(new_modules) > 0:
68 print "\nNouveaux modules: %s\n" % ", ".join(new_modules)
69 return 1, u("Nouveaux modules : %s" % ", ".join(new_modules))
70 else:
71 return 1, u("OK")
72
74 """Récupération de la table module depuis le backend
75 """
76 l=[]
77 for module in modules:
78 try:
79 self.parent.s_pool.check_mod_credential(cred_user, module[0])
80 except ResourceAuthError:
81
82 continue
83 if module[2] == None:
84 version = 1
85 else:
86 version = module[2]
87 l.append({'id':module[0],'libelle':module[1],'version':version})
88 return 1,u(l)
89
90
91
92
93
94
96 """ajoute un module dans la base de données et crée l'arborescence correspondante"""
97
98 if libelle:
99 query = """insert into modules (libelle, version) values ('%s',%s)""" % (libelle.replace("'","\\\'"),int(version))
100
101 return self.dbpool.runOperation(query).addCallbacks(self._add_module1,db_client_failed,callbackArgs=[libelle, version])
102 else:
103
104 return 0, u("""donnez un libellé""")
105
107 """récupère l'id du module créé"""
108
109 query="""select id from modules where libelle ilike '%s'""" % libelle.replace("'","\\\'")
110 return self.dbpool.runQuery(query).addCallbacks(self._add_module2,db_client_failed,callbackArgs=[libelle,version])
111
113 """crée la variante standard d'un nouveau module"""
114 if row ==[]:
115 return 0,u('erreur de création du module dans la base')
116 else:
117 id_module=row[0][0]
118
119 query = """insert into variantes (module,libelle) values (%s, 'standard')""" % id_module
120 return self.dbpool.runOperation(query).addCallbacks(self._add_module3,db_client_failed,callbackArgs=[id_module,libelle,version])
121
123 """récupère l'id de la variante standard"""
124 query = """select id,module from variantes where module = %s and libelle = 'standard'""" % id_module
125 return self.dbpool.runQuery(query).addCallbacks(self._add_module4,db_client_failed,callbackArgs=[libelle,version])
126
127
129 """met en place l'arborescence du nouveau module et de ses variantes"""
130 if row == []:
131 return 0,u('erreur de creation de la variante par défaut dans la base')
132 else:
133 id_variante = row[0][0]
134 id_module = row[0][1]
135
136 module_dir = os.path.abspath(config.PATH_MODULES)+os.sep+str(id_module)
137 try:
138 os.makedirs(module_dir)
139
140 if int(version) == 1:
141 dico_module=os.path.abspath(config.ROOT_DIR)+'/dictionnaires/dico-%s' % libelle
142 os.system('ln -s %s %s' % (dico_module,module_dir+os.sep+'dictionnaire'))
143 else:
144
145 dico_module=os.path.abspath(config.ROOT_DIR)+'/dictionnaires/%s' % libelle
146 if os.path.isdir(dico_module):
147
148 os.system('ln -s %s %s' % (dico_module, os.path.join(module_dir,'dicos')))
149
150 d = EoleDict()
151 d.read_dir(os.path.join(module_dir,'dicos'))
152
153 d.save_values(os.path.join(module_dir,'module.eol'),True)
154 else:
155
156 os.makedirs(os.path.join(module_dir,'dicos'))
157
158 os.makedirs(module_dir+os.sep+'variantes'+os.sep+str(id_variante)+os.sep+'dicos')
159 os.makedirs(module_dir+os.sep+'variantes'+os.sep+str(id_variante)+os.sep+'patchs')
160 os.makedirs(module_dir+os.sep+'variantes'+os.sep+str(id_variante)+os.sep+'fichiers_perso')
161 os.makedirs(module_dir+os.sep+'variantes'+os.sep+str(id_variante)+os.sep+'fichiers_zephir')
162 except:
163 try:
164 shutil.rmtree(module_dir)
165 except:
166
167 pass
168 query = """delete from variantes where module = %s""" % id_module
169 self.dbpool.runOperation(query)
170 query = """delete from modules where id = %s""" % id_module
171 self.dbpool.runOperation(query)
172 return 0, u("""erreur de creation de l'arborescence du module""")
173
174
175 return 1, u(id_module)
176
178 """supprime un module et ses variantes"""
179 if int(id_module) >= 0:
180 self.parent.s_pool.check_mod_credential(cred_user, id_module)
181
182 query = "delete from variantes where module = %d" % int(id_module)
183 return self.dbpool.runOperation(query).addCallbacks(self._del_module,db_client_failed,callbackArgs=[id_module])
184 else:
185 return 0, u("""donnez l'id d'un module (nombre entier)""")
186
188 """supprime de la base les services liés au module"""
189 query = "delete from services where module = %d" % int(id_module)
190 return self.dbpool.runOperation(query).addCallbacks(self._del_module1,db_client_failed,callbackArgs=[id_module])
191
193 """supprime le module dans la base de données"""
194 query = "delete from modules where id = %s" % id_module
195 return self.dbpool.runOperation(query).addCallbacks(self._del_module2,db_client_failed,callbackArgs=[id_module])
196
198 """supprime l'arborescence du module dans l'arborescence zephir"""
199 module_dir=os.path.abspath(config.PATH_MODULES)+os.sep+str(id_module)
200 try:
201 shutil.rmtree(module_dir)
202 except:
203 return 1,u("""erreur de supression du répertoire du module""")
204 return 1,u('ok')
205
207 """modification d'un module
208 cette fonction prend en compte un dictionnaire qui indique les
209 champs à modifier et leur nouvelle valeur. l'application cliente
210 doit s'assurer que ces champs existent dans la base"""
211 self.parent.s_pool.check_mod_credential(cred_user, id_module)
212 if dico_modifs == {}:
213 return 1,u("""aucune modification demandée""")
214
215 if 'id' in dico_modifs.keys():
216 return 0,u("""l'identifiant ne peut pas être modifié""")
217
218 requete=["update modules set "]
219 for cle in dico_modifs.keys():
220 requete.append(str(cle))
221 requete.append("='")
222 requete.append(str(dico_modifs[cle]).replace("'","\\\'"))
223 requete.append("', ")
224 string_fin=""" where id='%s'""" % id_module
225 query="".join(requete)[:-2]
226 query += string_fin
227 return self.dbpool.runOperation(query).addCallbacks(lambda x:(1,'ok'), db_client_failed)
228
230 """récupère un module précis dans la base ou tous les modules"""
231 if id_module :
232
233 query = """select id, libelle, version from modules where id = %s""" % id_module
234 return self.dbpool.runQuery(query).addCallbacks(self._got_modules,db_client_failed,callbackArgs=[cred_user])
235 else :
236
237 query = """select id, libelle, version from modules order by id"""
238 return self.dbpool.runQuery(query).addCallbacks(self._got_modules,db_client_failed,callbackArgs=[cred_user])
239
241 """récupération du dictionnaire d'un module (valeurs par défaut)"""
242
243 try:
244 query = "select version from modules where id = %d" % int(id_module)
245 except:
246 return 0, u("""donnez l'id d'un module (nombre entier)""")
247 return self.dbpool.runQuery(query).addCallbacks(self._get_dico,db_client_failed,callbackArgs=[id_module, id_variante])
248
249 - def _get_dico(self,data,id_module,id_variante=None):
250
251 try:
252 version = int(data[0][0])
253 except:
254 version = 2
255
256
257 if version == 1:
258
259 path_dico = os.path.abspath(config.PATH_ZEPHIR)+os.sep+'modules'+os.sep+str(id_module)+os.sep+'dictionnaire'
260
261 try:
262 fic = open(path_dico,'r')
263 except:
264 return 0, u("""dictionnaire non présent""")
265
266
267 lines = fic.readlines()
268 fic.close()
269 dictionnaire = [ unicode(line, 'ISO-8859-1').encode('UTF-8') for line in lines ]
270
271 if id_variante is not None:
272 dicos=os.path.abspath(config.PATH_ZEPHIR)+os.sep+'modules'+os.sep+str(id_module)+os.sep+'variantes'+os.sep+str(id_variante)+os.sep+'dicos'
273 for nom_fic in os.listdir(dicos):
274 if nom_fic.endswith('.eol') or nom_fic.endswith('.xml'):
275
276 fic = open(dicos+os.sep+nom_fic,'r')
277 lines = fic.readlines()
278 fic.close()
279 dictionnaire.extend([ unicode(line, 'ISO-8859-1').encode('UTF-8') for line in lines ])
280
281
282 dic_complet=dico.DicoEole(dico_zephir=[dictionnaire])
283
284
285 if id_variante is not None:
286 path_dicovar = os.path.abspath(config.PATH_ZEPHIR)+os.sep+'modules'+os.sep+str(id_module)+os.sep+'variantes'+os.sep+str(id_variante)+os.sep+'dico.eol'
287 if os.path.isfile(path_dicovar):
288
289
290 f=file(path_dicovar)
291 lines = f.readlines()
292 f.close()
293 data = [ unicode(line, 'ISO-8859-1').encode('UTF-8') for line in lines ]
294
295 dic_actuel=dico.DicoEole(dico_zephir=[data]).ParseDico()
296 dico_final = {}
297
298 for variable, data in dic_complet.dictionnaire.items():
299
300 if dic_actuel.has_key(data[0]):
301 data[1] = dic_actuel[data[0]][0]
302 dico_final[variable]=data
303
304 dic_complet.dictionnaire = dico_final
305
306 dicos=[base64.encodestring(dic_complet.save("/dev/null"))]
307 else:
308
309
310 path_module = os.path.abspath(config.PATH_ZEPHIR)+os.sep+'modules'+os.sep+str(id_module)
311 path_dico = path_module+os.sep+'dicos'
312
313 dict_dirs = [path_dico]
314 if id_variante is not None:
315 dict_dirs.append(os.path.join(path_module,'variantes',str(id_variante),'dicos'))
316
317 dict_zeph = ZephirDict(dicos=dict_dirs, confdir=path_dico, mode='config', version='creole2')
318 if os.path.isfile(os.path.join(path_module,'module.eol')):
319 dict_zeph.dico.load_values(os.path.join(path_module,'module.eol'))
320
321 if id_variante is not None:
322 path_var = os.path.join(path_module,'variantes',str(id_variante),'dico.eol')
323 dict_zeph.dico.load_values(os.path.join(path_var))
324 dicos = dict_zeph.get_dict()
325 if dicos == None:
326 dicos = []
327
328 return 1,u(dicos)
329
331 """récupération des libellés/familles des variables eole pour un module"""
332
333 try:
334 query = "select id,version from modules where id = %d" % int(id_module)
335 except:
336 return 0, u("""donnez l'id d'un module (nombre entier)""")
337 return self.dbpool.runQuery(query).addCallbacks(self._get_vars,db_client_failed)
338
340
341 try:
342 id_module = int(data[0][0])
343 except:
344 return 0, u("""module non trouvé""")
345 try:
346 version = int(data[0][1])
347 except:
348 version = 2
349
350 if version == 1:
351
352 creole_files = [os.path.abspath(config.PATH_ZEPHIR)+os.sep+'modules'+os.sep+str(id_module)+os.sep+'dictionnaire']
353
354 dicos = []
355 for dic in creole_files:
356 try:
357
358 fic = open(dic,'r')
359 lines = fic.readlines()
360 fic.close()
361 data = [ unicode(line, 'ISO-8859-1').encode('UTF-8') for line in lines ]
362
363 dicos.append(data)
364 except OSError:
365 pass
366 dict_zeph = ZephirDict(dicos=dicos, confdir='', mode='dico', version='creole1')
367 families = {}
368 else:
369
370
371 path_module = os.path.abspath(config.PATH_ZEPHIR)+os.sep+'modules'+os.sep+str(id_module)
372 path_dico = path_module+os.sep+'dicos'
373
374 dict_dirs = [path_dico]
375
376 dict_zeph = ZephirDict(dicos=dict_dirs, confdir=path_dico, mode='config', version='creole2')
377 families = {}
378 menu = dict_zeph.get_menu(True)
379 for family in menu:
380 for var in family[2]:
381 families[var] = family[0]
382
383
384 vars_dict = {}
385 try:
386 var_data = dict_zeph.get_first()
387 while 1:
388 if families.has_key(var_data[0]):
389 family = families[var_data[0]]
390 else:
391 family = ''
392 vars_dict[var_data[0]] = [var_data[2],family]
393 var_data = dict_zeph.get_next()
394 except:
395
396 pass
397
398 return 1,u(vars_dict)
399
401 """mise à jour du dictionnaire d'un module (valeurs par défaut)"""
402
403 self.parent.s_pool.check_mod_credential(cred_user, id_module)
404 if id_variante is not None:
405 self.parent.s_pool.check_var_credential(cred_user, id_variante)
406 query = """select id, libelle, version from modules where id=%s""" % id_module
407 return self.dbpool.runQuery(query).addCallbacks(self._save_dico, db_client_failed, callbackArgs=[dico_b64,id_variante])
408
409 - def _save_dico(self,data,dico_b64,id_variante=None):
410 if data == []:
411 return 0,u("""module non retrouvé""")
412
413 id_module = data[0][0]
414 libelle = data[0][1]
415 version = data[0][2]
416
417 if int(version) == 1:
418 try:
419
420 dico = base64.decodestring(dico_b64)
421
422 dico = unicode(dico,'UTF-8').encode('ISO-8859-1')
423
424 if id_variante is None:
425 path_dico = os.path.abspath(config.ROOT_DIR)+'/dictionnaires/dico-%s' % libelle
426 else:
427 path_dico = os.path.abspath(config.PATH_ZEPHIR)+os.sep+'modules'+os.sep+str(id_module)+os.sep+'variantes'+os.sep+str(id_variante)+os.sep+'dico.eol'
428 fic_zephir = open(path_dico,'w')
429 fic_zephir.write(dico)
430 fic_zephir.close()
431 except:
432 return 0,u("""erreur de sauvegarde du dictionnaire""")
433 elif int(version) == 2:
434 if id_variante is None:
435 path_dico = os.path.abspath(config.PATH_ZEPHIR)+os.sep+'modules'+os.sep+str(id_module)+os.sep+'module.eol'
436 else:
437 path_dico = os.path.abspath(config.PATH_ZEPHIR)+os.sep+'modules'+os.sep+str(id_module)+os.sep+'variantes'+os.sep+str(id_variante)+os.sep+'dico.eol'
438 values = eval(dico_b64[-1])
439 try:
440 parser = ConfigParser.ConfigParser()
441 parser._sections = values
442 fic_zephir = open(path_dico,'w')
443 parser.write(fic_zephir)
444 fic_zephir.close()
445 except:
446 return 0,u("""erreur de sauvegarde du dictionnaire""")
447
448 return 1,u('ok')
449
451 """renvoie la liste des dictionnaires d'un module.
452 utile pour les modules eole2 (fichier fixé pour les modules eole1)
453 """
454 self.parent.s_pool.check_mod_credential(cred_user, id_module)
455 query = "select id, version from modules where id=%s" % int(id_module)
456 return self.dbpool.runQuery(query).addCallbacks(self._get_mod_dict, db_client_failed)
457
459
460 id_module, version = data[0]
461 if version == 1:
462
463 return 1, []
464 try:
465 dest_dir=os.path.join(os.path.abspath(config.PATH_MODULES),str(id_module),"dicos")
466 content = []
467
468 for dict in os.listdir(dest_dir):
469 if dict.endswith('.xml'):
470 content.append(dict)
471 return 1, u(content)
472 except:
473 return 0,u("""erreur de parcours du répertoire des dictionnaires""")
474
476 """renvoie la liste des dictionnaires d'un module.
477 utile pour les modules eole2 (fichier fixé pour les modules eole1)
478 """
479
480 self.parent.s_pool.check_mod_credential(cred_user, id_module)
481 try:
482 fic_dest = os.path.join(os.path.abspath(config.PATH_MODULES),str(id_module),"dicos",dico_name)
483 assert os.path.isfile(fic_dest)
484 except:
485 return 0,u("""dictionnaire inexistant %s""" % dico_name)
486
487 try:
488 os.unlink(fic_dest)
489 return 1, "OK"
490 except:
491 return 0,u("""erreur lors de la suppression du dictionnaire""")
492
493
494
495
496
498 """formate les données lues dans la table variantes pour
499 l'envoyer à une application zephir (liste de dictionnaires)"""
500 l=[]
501 for variante in variantes:
502 owner = variante[3]
503 if owner == None:
504 owner = ""
505 try:
506 self.parent.s_pool.check_var_credential(cred_user, variante[0])
507 except ResourceAuthError:
508
509 continue
510 l.append({'id':variante[0],'module':variante[1],'libelle':variante[2],'owner':owner})
511 return 1,u(l)
512
514 """Copie une variante exisante sur une nouvelle variante"""
515
516 try:
517 id_variante=int(id_variante)
518 module=int(module)
519 assert libelle != ""
520 except:
521 return 0, u("""paramètres invalides""")
522
523 query = """insert into variantes (module,libelle,owner,passmd5) values (%s,'%s','%s','%s')""" % (module,libelle.replace("'","\\\'"),cred_user,passmd5)
524
525
526 return self.dbpool.runOperation(query).addCallbacks(self._copy_variante, db_client_failed,callbackArgs=[libelle,module,id_variante])
527
529 """recherche de l'id de la variante créée"""
530
531 query = """select * from variantes where libelle = '%s' and module = %s""" % (libelle.replace("'","\\\'"), module)
532 return self.dbpool.runQuery(query).addCallbacks(self._copy_variante2, db_client_failed,callbackArgs=[id_variante])
533
535 """copie l'arborescence de la variante source"""
536 try:
537 var_dest = data[0][0]
538 module = data[0][1]
539 libelle = data[0][2]
540 except:
541
542 return 0,u("""nouvelle variante non retrouvée dans la base""")
543 else:
544
545 rep_src=os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+os.sep+'variantes'+os.sep+str(var_src)
546 rep_dest=os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+os.sep+'variantes'+os.sep+str(var_dest)
547 try:
548 shutil.copytree(rep_src,rep_dest)
549 except:
550 return 0,u("""erreur de copie de l'arborescence de la variante""")
551 return 1,var_dest
552
553
555 """ajoute une variante à un module"""
556 self.parent.s_pool.check_mod_credential(cred_user, module)
557
558 if module and libelle:
559 query = """insert into variantes (module,libelle,owner,passmd5) values (%s,'%s','%s','%s')""" % (module,libelle.replace("'","\\\'"),cred_user,pass_var)
560
561
562 return self.dbpool.runOperation(query).addCallbacks(self._add_variante1, db_client_failed,callbackArgs=[libelle,module])
563 else:
564
565 return 0, u("""donnez un id de module et un libellé""")
566
568 """recherche de l'id de la variante créée"""
569
570 query = """select * from variantes where libelle ilike '%s' and module = %s""" % (libelle.replace("'","\\\'"), module)
571 return self.dbpool.runQuery(query).addCallbacks(self._add_variante2,db_client_failed)
572
574 """met en place l'arborescence d'une nouvelle variante"""
575 try:
576 id_variante = variante[0][0]
577 module = variante[0][1]
578 libelle = variante[0][2]
579 except:
580
581 return 0,u("""nouvelle variante non retrouvée dans la base""")
582 else:
583
584 os.makedirs(os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+os.sep+'variantes'+os.sep+str(id_variante))
585 os.makedirs(os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+os.sep+'variantes'+os.sep+str(id_variante)+os.sep+'patchs')
586 os.makedirs(os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+os.sep+'variantes'+os.sep+str(id_variante)+os.sep+'dicos')
587 os.makedirs(os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+os.sep+'variantes'+os.sep+str(id_variante)+os.sep+'fichiers_perso')
588 os.makedirs(os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+os.sep+'variantes'+os.sep+str(id_variante)+os.sep+'fichiers_zephir')
589 return 1,id_variante
590
591
593 """suppression d'une variante de la base zephir"""
594 self.parent.s_pool.check_var_credential(cred_user, id_variante)
595 if id_variante:
596 query = """select * from variantes where id = %s""" % id_variante
597
598 return self.dbpool.runQuery(query).addCallbacks(self._del_variante, db_client_failed)
599 else:
600 return 0,u("""donnez un identifiant de variante""")
601
603 """supprime la variante de la base de données"""
604 try:
605 id_variante = variante[0][0]
606 id_module = variante[0][1]
607 libelle = variante[0][2]
608 except:
609
610 return 0,u("""variante non trouvée dans la base""")
611 else:
612
613 if libelle == 'standard':
614 return 0, u("""la variante standard ne peut pas être supprimée""")
615
616 query = """delete from variantes where id = %s""" % id_variante
617 return self.dbpool.runOperation(query).addCallbacks(self._del_variante2, db_client_failed,callbackArgs=[id_module,id_variante])
618
620 """supression de l'arborescence de la variante"""
621
622 variante_dir=os.path.abspath(config.PATH_MODULES)+os.sep+str(id_module)+os.sep+"variantes"+os.sep+str(id_variante)
623 try:
624 shutil.rmtree(variante_dir)
625 except:
626
627 return 0,u("""erreur de supression du répertoire de la variante""")
628 return 1, u('ok')
629
631 """ retourne la liste des fichiers personnalisés pour cette variante """
632 self.parent.s_pool.check_var_credential(cred_user, id_variante)
633 query = """select id,module from variantes where id = %s""" % id_variante
634 return self.dbpool.runQuery(query).addCallbacks(self._fichiers_zephir,db_client_failed)
635
637 """recherche les fichiers liés à une variante"""
638 if data == []:
639 return 0,u("serveur inconnu de zephir")
640 else:
641 id_variante = int(data[0][0])
642 id_module = int(data[0][1])
643
644 variante_dir = os.path.abspath(config.PATH_ZEPHIR)+os.sep+'modules'+os.sep+str(id_module)+os.sep+'variantes'+os.sep+str(id_variante)
645
646 dico_res={}
647 try:
648
649 liste_dicos = []
650 liste_dicos_var = []
651 for fic in os.listdir(variante_dir+os.sep+'dicos'):
652 if fic.endswith('.eol') or fic.endswith('.xml'):
653 liste_dicos_var.append(fic)
654 dico_res['dicos_var'] = liste_dicos_var
655 except OSError:
656 dico_res['dicos_var'] = ['répertoire non trouvé !']
657 try:
658
659 dico_res['persos_var'] = (os.listdir(variante_dir+os.sep+'fichiers_perso'))
660 except OSError:
661 dico_res['persos_var'] = ['répertoire non trouvé !']
662 try:
663
664 dico_res['patchs_var'] = os.listdir(variante_dir+os.sep+'patchs')
665 except OSError:
666 dico_res['patchs_var'] = ['répertoire non trouvé !']
667 try:
668
669
670 fic = open(variante_dir+'/fichiers_zephir/fichiers_variante')
671 data = fic.read().split("\n")
672 fic.close()
673
674 liste_pkg_var = []
675 section_rpm = 0
676 for ligne in data:
677 ligne = ligne.strip()
678 if section_rpm == 1:
679
680 if not ligne.startswith('#') and ligne != '':
681
682 liste_pkg_var.append(ligne)
683 if ligne == '%%':
684 section_rpm = 1
685 dico_res['rpms_var'] = liste_pkg_var
686 except IOError:
687 dico_res['rpms_var'] = []
688 try:
689
690 liste_fic=[]
691 try:
692 f=open(variante_dir+os.sep+'fichiers_zephir/fichiers_variante')
693 old_content=f.read()
694 f.close()
695 fichiers=old_content.split('%%\n')[0]
696 except:
697 fichiers=""
698 for f in fichiers.split('\n'):
699 if f.strip().startswith("""/"""):
700 liste_fic.append(f)
701 dico_res['fichiers_var'] = liste_fic
702
703
704
705
706 except:
707 dico_res['fichiers_var'] = ['répertoire non trouvé !']
708 return 1,u(dico_res)
709
711 """renvoie les informations de permissions associées à un(des) fichier(s)
712 """
713
714 query = """select id,module from variantes where id=%s""" % id_variante
715 return self.dbpool.runQuery(query).addCallbacks(self._get_variante_perms,db_client_failed,callbackArgs=[filepath])
716
718 """crée l'archive de la variante et la renvoie"""
719 if data != []:
720 id_variante = data[0][0]
721 id_module = data[0][1]
722
723 var_dir=os.path.abspath(config.PATH_MODULES)+os.sep+str(id_module)+os.sep+"variantes"+os.sep+str(id_variante)
724 try:
725 id_var = int(id_variante)
726
727 except KeyError, ValueError:
728 return 0, u("""variante inconnue : %s""" % str(id_var))
729 else:
730 result = self.parent.s_pool.get_file_perms(var_dir, filepath)
731 return 1, u(result)
732
734 """supprime les informations de permissions associées à un(des) fichier(s)
735 """
736
737 query = """select id,module from variantes where id=%s""" % id_variante
738 return self.dbpool.runQuery(query).addCallbacks(self._del_variante_perms,db_client_failed,callbackArgs=[filepath])
739
741 """crée l'archive de la variante et la renvoie"""
742 if data != []:
743 id_variante = data[0][0]
744 id_module = data[0][1]
745
746 var_dir=os.path.abspath(config.PATH_MODULES)+os.sep+str(id_module)+os.sep+"variantes"+os.sep+str(id_variante)
747 try:
748 id_var = int(id_variante)
749 except KeyError, ValueError:
750 return 0, u("""variante inconnue : %s""" % str(id_var))
751 else:
752 result = self.parent.s_pool.del_file_perms(var_dir, filepath)
753 return 1, u(result)
754
756 """enregistre les informations de permissions associées à un(des) fichier(s)
757 @param rights: dictionnaire au format suviant : {'filepath':[mode,ownership]}
758 """
759
760 query = """select id,module from variantes where id=%s""" % id_variante
761 return self.dbpool.runQuery(query).addCallbacks(self._set_variante_perms,db_client_failed,callbackArgs=[rights])
762
764 """crée l'archive de la variante et la renvoie"""
765 if data != []:
766 id_variante = data[0][0]
767 id_module = data[0][1]
768
769 var_dir=os.path.abspath(config.PATH_MODULES)+os.sep+str(id_module)+os.sep+"variantes"+os.sep+str(id_variante)
770 try:
771 id_var = int(id_variante)
772 except KeyError, ValueError:
773 return 0, u("""variante inconnue : %s""" % str(id_var))
774 else:
775 res = self.parent.s_pool.set_file_perms(rights, var_dir)
776 if res:
777 return 1,"OK"
778 else:
779 return 0, u("""erreur d'enregistrement des permissions""")
780
782 """récupère la liste d'une variante (ou toutes)"""
783 if id_variante :
784 query = """select * from variantes where id = %s """ % id_variante
785 return self.dbpool.runQuery(query).addCallbacks(self._got_variantes,db_client_failed,callbackArgs=[cred_user])
786 else :
787 query = """select * from variantes"""
788 return self.dbpool.runQuery(query).addCallbacks(self._got_variantes,db_client_failed,callbackArgs=[cred_user])
789
791 """modification d'une variante
792 cette fonction prend en compte un dictionnaire qui indique les
793 champs à modifier et leur nouvelle valeur. l'application cliente
794 doit s'assurer que ces champs existent dans la base"""
795 self.parent.s_pool.check_var_credential(cred_user, id_variante)
796
797 if dico_modifs == {}:
798 return 1,u("""aucune modification demandée""")
799 if ('id' in dico_modifs.keys()) or ('module' in dico_modifs.keys()):
800 return 0,u("""l'identifiant et le module ne peuvent pas être modifiés""")
801 if ('owner' in dico_modifs.keys()) or ('passmd5' in dico_modifs.keys()):
802 return 0,u("""modification du propriétaire ou mot de passe interdits""")
803
804 requete=["update variantes set "]
805 for cle in dico_modifs.keys():
806 requete.append(str(cle))
807 requete.append("='")
808 requete.append(str(dico_modifs[cle]).replace("'","\\\'"))
809 requete.append("', ")
810 string_fin=""" where id='%s'""" % id_variante
811 query="".join(requete)[:-2]
812 query += string_fin
813 return self.dbpool.runOperation(query).addCallbacks(lambda x:(1,'ok'), db_client_failed)
814
815 - def xmlrpc_add_files(self,cred_user,id_variante,dico_files,passwd="",encode=False):
816 """ajoute des fichiers, patchs, dictionnaires à une variante
817 """
818 self.parent.s_pool.check_var_credential(cred_user, id_variante)
819 query="select modules.version,variantes.id,variantes.module,variantes.owner,variantes.passmd5 from variantes,modules where variantes.id=%s and modules.id=variantes.module" % id_variante
820 return self.dbpool.runQuery(query).addCallbacks(self._add_files,db_client_failed,callbackArgs=[dico_files,cred_user,passwd,encode])
821
822 - def _add_files(self,data,dico_files,cred_user,passwd,encode):
823 """ajoute des fichiers, patchs, dictionnaires,rpms à une variante
824 """
825 mod_version = data[0][0]
826 id_variante = data[0][1]
827 id_module = data[0][2]
828 owner = data[0][3]
829 pass_var = data[0][4]
830
831 if owner != cred_user:
832
833 if passwd != pass_var and pass_var not in [None,'']:
834
835 return 0,u('mot de passe incorrect pour cette variante')
836
837 dest_dir=os.path.abspath(config.PATH_MODULES)+os.sep+str(id_module)+os.sep+"variantes"+os.sep+str(id_variante)
838
839 if int(mod_version) == 1 and encode == True:
840 for type_f, files in dico_files.items():
841 if type_f in ['dicos_var','patchs_var','persos_var','fichiers_var']:
842 encoded_files = []
843 for fichier in dico_files[type_f]:
844 content = unicode(base64.decodestring(fichier[1]),config.charset).encode('ISO-8859-1')
845 localpath = ""
846 if len(fichier) == 3:
847 localpath = fichier[2]
848 encoded_files.append([fichier[0], base64.encodestring(content),localpath])
849 dico_files[type_f] = encoded_files
850
851 for dico in dico_files['dicos_var']:
852 try:
853 if dico[0] != "":
854 f=open(dest_dir+os.sep+'dicos'+os.sep+os.path.basename(dico[0].replace("\\","/")),'w')
855 f.write(base64.decodestring(dico[1]))
856 f.close()
857 except:
858 return 0,u("erreur de sauvegarde de %s" % dico)
859 for template in dico_files['persos_var']:
860 try:
861 if template[0] != "":
862 f=open(dest_dir+os.sep+'fichiers_perso'+os.sep+os.path.basename(template[0].replace("\\","/")),'w')
863 f.write(base64.decodestring(template[1]))
864 f.close()
865 except:
866 return 0,u("erreur de sauvegarde de %s" % template)
867 for patch in dico_files['patchs_var']:
868 try:
869 if patch[0] != "":
870 f=open(dest_dir+os.sep+'patchs'+os.sep+os.path.basename(patch[0].replace("\\","/")),'w')
871 f.write(base64.decodestring(patch[1]))
872 f.close()
873 except:
874 return 0,u("erreur de sauvegarde de %s" % patch)
875
876 try:
877 f=open(dest_dir+os.sep+'fichiers_zephir/fichiers_variante')
878 old_content=f.read()
879 f.close()
880 fichiers=old_content.split('%%\n')[0]
881 rpms=old_content.split('%%\n')[1]
882 except:
883 fichiers="""# section 1
884 # liste des fichiers à sauvegarder+# (ne pas modifier sauf pour créer ou mettre à jour la variante)"""
885 rpms="""# section 2
886 # inscrire les noms des paquetages qui seront installés à la mise à jour du serveur
887 # (ils doivent être présents sur le serveur de mise à jour)"""
888
889 for fichier in dico_files['fichiers_var']:
890
891 localpath = ""
892 if len(fichier) == 3:
893 localpath = fichier[2]
894
895 nom_fic = fichier[0].replace("\\","/")
896
897 if fichier[0].endswith('/'):
898 nom_fic = fichier[0][:-1]
899 if fichier[0].endswith("\\"):
900 nom_fic = fichier[0][:-2]
901 if nom_fic not in fichiers.split('\n') and localpath == "":
902 fichiers = fichiers.strip() + '\n' + nom_fic +'\n'
903
904 try:
905 if nom_fic != "":
906 if localpath == "":
907 f=open(os.path.join(dest_dir,'fichiers_zephir',os.path.basename(nom_fic)),'w')
908 else:
909 f=open(os.path.join(dest_dir,localpath,os.path.basename(nom_fic)),'w')
910 f.write(base64.decodestring(fichier[1]))
911 f.close()
912 except:
913 return 0,u("erreur de sauvegarde de %s" % fichier)
914
915
916 for rpm in dico_files['rpms_var']:
917
918 if rpm not in rpms.split('\n'):
919 rpms = rpms.strip() + '\n' + rpm +'\n'
920
921 f=open(dest_dir+os.sep+'fichiers_zephir/fichiers_variante','w')
922 f.write(fichiers+"%%\n"+rpms)
923 f.close()
924 return 1,u("ok")
925
927 """suppression de fichiers, patchs, dictionnaires d'une variante
928 """
929 self.parent.s_pool.check_var_credential(cred_user, id_variante)
930 query="select id,module,owner,passmd5 from variantes where id=%s" % id_variante
931 return self.dbpool.runQuery(query).addCallbacks(self._del_files,db_client_failed,callbackArgs=[dico_files,cred_user,passwd])
932
933 - def _del_files(self,data,dico_files,cred_user,passwd):
934 """supression de fichiers, patchs, dictionnaires,rpms d'une variante
935 """
936 id_variante = data[0][0]
937 id_module = data[0][1]
938 owner = data[0][2]
939 pass_var = data[0][3]
940
941 if owner != cred_user:
942
943 if passwd != pass_var and pass_var not in [None,'']:
944
945 return 0,u('mot de passe incorrect pour cette variante')
946
947 dest_dir=os.path.abspath(config.PATH_MODULES)+os.sep+str(id_module)+os.sep+"variantes"+os.sep+str(id_variante)
948
949 for dico in dico_files['dicos_var']:
950 try:
951 if dico != "":
952 os.unlink(dest_dir+os.sep+'dicos'+os.sep+dico)
953 except:
954 return 0,u("erreur de suppression de %s" % dico)
955 for template in dico_files['persos_var']:
956 try:
957 if template != "":
958 os.unlink(dest_dir+os.sep+'fichiers_perso'+os.sep+template)
959 except:
960 return 0,u("erreur de supression de %s" % template)
961
962 self.parent.s_pool.del_file_perms(dest_dir,'fichiers_perso'+os.sep+template)
963
964 for patch in dico_files['patchs_var']:
965 try:
966 if patch != "":
967 os.unlink(dest_dir+os.sep+'patchs'+os.sep+patch)
968 except:
969 return 0,u("erreur de suppression de %s" % patch)
970
971 try:
972 f=open(dest_dir+os.sep+'fichiers_zephir/fichiers_variante')
973 old_content=f.read()
974 f.close()
975 fichiers=old_content.split('%%\n')[0]
976 rpms=old_content.split('%%\n')[1]
977 except:
978 fichiers="""# section 1
979 # liste des fichiers à sauvegarder pour la variante
980 # (ne pas modifier sauf pour créer ou mettre à jour la variante)"""
981 rpms="""# section 2
982 # inscrire les noms des paquetages qui seront installés à la mise à jour du serveur
983 # (ils doivent être présents sur le serveur de mise à jour)"""
984
985 for fichier in dico_files['fichiers_var']:
986
987 liste=fichiers.split('\n')
988 if fichier in liste:
989 liste.remove(fichier)
990 fichiers = "\n".join(liste)
991 fic_path = os.path.join(dest_dir,'fichiers_zephir',os.path.basename(fichier.replace("\\","/")))
992 else:
993 fic_path = os.path.join(dest_dir,fichier)
994
995 try:
996 if fichier != "":
997 if os.path.isdir(fic_path):
998 shutil.rmtree(fic_path)
999 else:
1000 os.unlink(fic_path)
1001 except:
1002 return 0,u("erreur de suppression de %s" % fichier)
1003 if fichier.startswith('/'):
1004 fic_sup = 'fichiers_zephir/'+os.path.basename(fichier.replace("\\","/"))
1005 else:
1006 fic_sup = fichier
1007 self.parent.s_pool.del_file_perms(dest_dir,fic_sup,True)
1008
1009
1010 for rpm in dico_files['rpms_var']:
1011
1012 liste=rpms.split('\n')
1013 if rpm in liste:
1014 liste.remove(rpm)
1015 rpms = "\n".join(liste)
1016 else:
1017 return 0,u("rpm non trouvé dans la liste : %s" % rpm)
1018
1019 f=open(dest_dir+os.sep+'fichiers_zephir/fichiers_variante','w')
1020 f.write(fichiers+"%%\n"+rpms)
1021 f.close()
1022 return 1,u("ok")
1023
1025 """renvoie le contenu d'un fichier de variante"""
1026
1027 self.parent.s_pool.check_var_credential(cred_user, id_var)
1028 query="select variantes.id,variantes.module,modules.version from variantes,modules where variantes.id=%s and modules.id=variantes.module" % id_var
1029 return self.dbpool.runQuery(query).addCallbacks(self._get_var_file,db_client_failed,callbackArgs=[path])
1030
1032 id_var = data[0][0]
1033 id_module = data[0][1]
1034 mod_version = data[0][2]
1035 try:
1036 dest_dir=os.path.abspath(config.PATH_MODULES)+os.sep+str(id_module)+os.sep+"variantes"+os.sep+str(id_var)
1037 except:
1038 return 0,u("""lecture du fichier: paramètres non valides""")
1039
1040 try:
1041
1042 if os.path.isdir(dest_dir + os.sep + path):
1043 content = os.listdir(dest_dir + os.sep + path)
1044 return 1, u(content)
1045 else:
1046 if istextfile(dest_dir + os.sep + path):
1047 f=file(dest_dir + os.sep + path)
1048 content=f.read()
1049 f.close()
1050
1051 if int(mod_version) == 1:
1052 try:
1053 content = unicode(content,'ISO-8859-1').encode(config.charset)
1054 except:
1055
1056 print "echec d'encoding du fichier %s provenant d'un serveur eole1" % path
1057 content = base64.encodestring(content)
1058 else:
1059 content = "BINARY"
1060 return 1, content
1061 except:
1062 return 0,u("""erreur de lecture du fichier""")
1063
1065 """envoie le contenu d'une variante sur un autre zephir"""
1066
1067 query = """select id,module from variantes where id=%s""" % id_variante
1068 return self.dbpool.runQuery(query).addCallbacks(self._export_variante,db_client_failed)
1069
1071 """crée l'archive de la variante et le renvoie"""
1072 if data != []:
1073 id_variante = data[0][0]
1074 id_module = data[0][1]
1075
1076 parent_dir=os.path.abspath(config.PATH_MODULES)+os.sep+str(id_module)+os.sep+"variantes"
1077 var_dir=parent_dir+os.sep+str(id_variante)
1078
1079 archive=str(time.time())
1080 if os.path.isdir(var_dir):
1081
1082 cmd_tar = ['cd ',var_dir,';','tar','-chzf','/tmp/'+archive+'.tgz','*']
1083 cmd_tar.append('2>&1 >/dev/null')
1084
1085 res=os.system(" ".join(cmd_tar))
1086 if res != 0:
1087 return 0, u("""erreur de création de l'archive %s.tgz dans /tmp""" % (archive))
1088 else:
1089
1090 cmd_checksum = """cd /tmp/; md5sum -b %s.tgz > %s.md5""" % (archive,archive)
1091 res=os.system(cmd_checksum)
1092
1093 try:
1094
1095 f = open('/tmp'+os.sep+archive+'.md5')
1096 data1 = f.read()
1097 f.close()
1098 os.unlink('/tmp'+os.sep+archive+'.md5')
1099
1100 f = open('/tmp'+os.sep+archive+'.tgz')
1101 data2 = f.read()
1102 f.close()
1103 os.unlink('/tmp'+os.sep+archive+'.tgz')
1104 return 1,u([archive,base64.encodestring(data1),base64.encodestring(data2)])
1105 except Exception, e:
1106 return 0,u("""erreur lors de l'envoi de l'archive : %s""" % str(e))
1107 else:
1108 return 0, u("""répertoire %s introuvable""" % var_dir)
1109 else:
1110 return 0, u("""variante inexistante""")
1111
1112 - def xmlrpc_import_variante(self,cred_user,pwd_var,id_local,id_distant,zephir_distant,login_distant,pwd_distant):
1113 """récupère le contenu d'une variante sur un autre zephir"""
1114
1115 z=xmlrpclib.ServerProxy("https://%s:%s@%s:%s" % (login_distant,pwd_distant,zephir_distant,config.PORT_ZEPHIR))
1116
1117 try:
1118 res=z.modules.get_variante(id_distant)
1119 except:
1120 return 0,u("""permissions insuffisantes""")
1121 if res[0] == 0:
1122 return 0,u("""erreur lors de la recherche de la variante d'origine""")
1123
1124
1125 query = """select id, module, owner, passmd5 from variantes where id=%s""" % id_local
1126 return self.dbpool.runQuery(query).addCallbacks(self._import_variante,db_client_failed,callbackArgs=[z,id_distant,cred_user,pwd_var])
1127
1129 """demande l'envoi de l'archive et met en place les fichiers"""
1130 if data == []:
1131 return 0, u("""variante locale non trouvée""")
1132 else:
1133 id_variante = data[0][0]
1134 id_module = data[0][1]
1135 owner = data[0][2]
1136 passmd5 = data[0][3]
1137
1138 if owner != cred_user and pwd_var != passmd5:
1139 return 0,u("""mauvais mot de passe de variante""")
1140 else:
1141
1142 parent_dir=os.path.abspath(config.PATH_MODULES)+os.sep+str(id_module)+os.sep+"variantes"
1143 var_dir = parent_dir+os.sep+str(id_variante)
1144
1145 if not os.path.exists(var_dir):
1146 return 0,u("""répertoire de la variante de destination non trouvé""")
1147
1148 res=proxy.modules.export_variante(id_distant)
1149 if res[0]==0:
1150 return 0,u("""erreur lors de la récupération de la variante""")
1151 else:
1152
1153 archive=res[1][0]
1154
1155 var_data=base64.decodestring(res[1][1])
1156
1157 md5_data=base64.decodestring(res[1][2])
1158 try:
1159
1160 shutil.rmtree(var_dir)
1161
1162 os.makedirs(var_dir)
1163
1164 f=open(var_dir+os.sep+archive+'.tgz','w')
1165 f.write(md5_data)
1166 f.close()
1167 f=open(var_dir+os.sep+archive+'.md5','w')
1168 f.write(var_data)
1169 f.close()
1170
1171 cmd_md5 = """cd %s; md5sum -c %s.md5 2>&1 > /dev/null""" % (var_dir,archive)
1172 res=os.system(cmd_md5)
1173 if res != 0:
1174 return 0,u("""archive corrompue""")
1175
1176 cmd_tar = """cd %s ; tar -xzf %s.tgz > /dev/null""" % (var_dir,archive)
1177 res=os.system(cmd_tar)
1178 if res != 0:
1179 return 0,u("""erreur de décompression de l'archive""")
1180
1181 os.unlink(var_dir+os.sep+archive+'.tgz')
1182 os.unlink(var_dir+os.sep+archive+'.md5')
1183 except Exception, e:
1184 return 0,u("""erreur de mise en place des fichiers de la variante : %s""" % str(e))
1185
1186 return 1,u("ok")
1187