1
2
3
4
5
6
7
8
9
10
11
12
13 """module de gestion des modules Eole
14 """
15 from zephir.backend.db_utils import *
16 from zephir.backend import config
17 from zephir.backend.config import u, log
18 from zephir.backend.xmlrpceole import XMLRPCEole as XMLRPC
19 from zephir.backend.lib_backend import ResourceAuthError, istextfile, cx_pool
20 from zephir.utils.creolewrap import ZephirDict
21
22
23 import sys,os,shutil,time,dico,base64,ConfigParser,traceback,cjson
24 from hashlib import md5
25 from zephir.eolerpclib import xmlrpclib, EoleProxy
26 from creole.cfgparser import EoleDict, eosfunc
27 from twisted.python import syslog
28 from twisted.internet import defer
29
30 BLANK_MD5 = md5('').hexdigest()
31
33 """serveur XMLRPC zephir pour la gestion des modules Eole
34 """
35
37 self.dbpool = db_connect()
38 self.dbpool.noisy = 0
39 self.parent = parent
40
41 XMLRPC.__init__(self)
42
44 self.old_obs = log.theLogPublisher.observers[0]
45 new_obs = syslog.SyslogObserver('zephir_backend', options=syslog.DEFAULT_OPTIONS, facility=syslog.DEFAULT_FACILITY)
46 log.addObserver(new_obs.emit)
47 log.removeObserver(self.old_obs)
48 self.xmlrpc_update_modules()
49
51 if self.old_obs:
52 log.removeObserver(log.theLogPublisher.observers[0])
53 log.addObserver(self.old_obs)
54
56 """vérification de la liste des modules"""
57 cursor = cx_pool.create()
58 try:
59 cursor.execute("""select id, libelle, version from modules""")
60 modules_actuels = cursor.fetchall()
61 libelle_modules = [module[1] for module in modules_actuels]
62 except:
63 cx_pool.close(cursor)
64
65 log.msg("\nErreur de lecture de la liste des modules\n")
66 return 0, u("Erreur de lecture de la liste des modules")
67 cx_pool.close(cursor)
68 d_list = []
69 new_modules = []
70 for version, modules in config.liste_modules.items():
71 for module in modules:
72
73 if module not in libelle_modules and version > 1:
74 try:
75 new_modules.append(module)
76 d_list.append(self.xmlrpc_add_module("", module, version, True))
77 except:
78 return 0, u("erreur d'ajout du module %s" % module)
79 d = defer.DeferredList(d_list, consumeErrors=True)
80 d.addBoth(self._update_module, new_modules)
81
83
84 for index, libelle in enumerate(new_modules):
85 if result[index][0] == True:
86 log.msg(u"\nNouveau module créé: %s (%s)" % (libelle, result[index][1]))
87 else:
88 log.msg(u"\nErreur de création du module %s : %s" % (libelle, result[index][1]))
89 if len(new_modules) > 0:
90
91 self.parent.dictpool.update_data()
92 self.parent.dictpool.reset_modules()
93 return 1, u("Nouveaux modules : %s" % ", ".join(new_modules))
94 else:
95 return 1, u("OK")
96
113
114
115
116
117
118
120 """ajoute un module dans la base de données et crée l'arborescence correspondante
121 @param auto: si True, on ne met pas à jour le pool de dictionnaires.
122 Limite les traitements au démarrage (update_modules)
123 """
124
125 if libelle:
126 query = """insert into modules (libelle, version) values (%s,%s)"""
127 params = (libelle, int(version))
128
129 return self.dbpool.runOperation(query, params).addCallbacks(self._add_module1,db_client_failed,callbackArgs=[libelle, version, auto])
130 else:
131
132 return 0, u("""donnez un libellé""")
133
135 """récupère l'id du module créé"""
136
137 query="""select id from modules where libelle ilike %s"""
138 return self.dbpool.runQuery(query, (libelle,)).addCallbacks(self._add_module2,db_client_failed,callbackArgs=[libelle,version,auto])
139
141 """crée la variante standard d'un nouveau module"""
142 if row ==[]:
143 return 0,u('erreur de création du module dans la base')
144 else:
145 id_module=row[0][0]
146
147 query = """insert into variantes (module,libelle) values (%s, 'standard')"""
148 return self.dbpool.runOperation(query, (int(id_module),)).addCallbacks(self._add_module3,db_client_failed,callbackArgs=[id_module,libelle,version,auto])
149
150 - def _add_module3(self, resultat, id_module, libelle, version, auto):
151 """récupère l'id de la variante standard"""
152 query = """select id,module from variantes where module = %s and libelle = 'standard'"""
153 return self.dbpool.runQuery(query, (int(id_module),)).addCallbacks(self._add_module4,db_client_failed,callbackArgs=[libelle,version,auto])
154
155
157 """met en place l'arborescence du nouveau module et de ses variantes"""
158 if row == []:
159 return 0,u('erreur de creation de la variante par défaut dans la base')
160 else:
161 id_variante = row[0][0]
162 id_module = row[0][1]
163
164 module_dir = os.path.abspath(config.PATH_MODULES)+os.sep+str(id_module)
165 try:
166 if not os.path.isdir(module_dir):
167 os.makedirs(module_dir)
168
169 if int(version) == 1:
170 dico_module = os.path.abspath(config.ROOT_DIR)+'/dictionnaires/dico-%s' % libelle
171 os.system('ln -s %s %s' % (dico_module,module_dir+os.sep+'dictionnaire'))
172 else:
173
174 dico_module=os.path.abspath(config.ROOT_DIR)+'/dictionnaires/%s' % libelle
175 if os.path.isdir(dico_module):
176
177 os.system('ln -s %s %s' % (dico_module, os.path.join(module_dir,'dicos')))
178
179 d = EoleDict()
180 d.read_dir(os.path.join(module_dir,'dicos'))
181 else:
182 os.makedirs(os.path.join(module_dir,'dicos'))
183
184 os.makedirs(module_dir+os.sep+'variantes'+os.sep+str(id_variante)+os.sep+'dicos')
185 os.makedirs(module_dir+os.sep+'variantes'+os.sep+str(id_variante)+os.sep+'patchs')
186 os.makedirs(module_dir+os.sep+'variantes'+os.sep+str(id_variante)+os.sep+'fichiers_perso')
187 os.makedirs(module_dir+os.sep+'variantes'+os.sep+str(id_variante)+os.sep+'fichiers_zephir')
188 except:
189 traceback.print_exc()
190 try:
191 shutil.rmtree(module_dir)
192 except:
193
194 pass
195 query = """delete from variantes where module = %s"""
196 self.dbpool.runOperation(query, (int(id_module),))
197 query = """delete from modules where id = %s"""
198 self.dbpool.runOperation(query, (int(id_module),))
199 return 0, u("""erreur de creation de l'arborescence du module %s""" % libelle)
200
201 self.parent.s_pool.stats['serv_modules'][str(id_module)] = 0
202 self.parent.s_pool.stats['serv_variantes'][str(id_variante)] = 0
203
204 if not auto:
205 self.parent.dictpool.update_data()
206 return 1, u(id_module)
207
209 """supprime un module et ses variantes"""
210 if int(id_module) >= 0:
211 self.parent.s_pool.check_mod_credential(cred_user, id_module)
212
213 query = "delete from variantes where module = %s"
214 return self.dbpool.runOperation(query, (int(id_module),)).addCallbacks(self._del_module,db_client_failed,callbackArgs=[id_module])
215 else:
216 return 0, u("""donnez l'id d'un module (nombre entier)""")
217
219 """supprime de la base les services liés au module"""
220 query = "delete from services where module = %s"
221 return self.dbpool.runOperation(query, (int(id_module),)).addCallbacks(self._del_module1,db_client_failed,callbackArgs=[id_module])
222
224 """supprime le module dans la base de données"""
225 query = "delete from modules where id = %s"
226 return self.dbpool.runOperation(query, (int(id_module),)).addCallbacks(self._del_module2,db_client_failed,callbackArgs=[id_module])
227
229 """supprime l'arborescence du module dans l'arborescence zephir"""
230
231 if str(id_module) in self.parent.s_pool.stats['serv_modules']:
232 del(self.parent.s_pool.stats['serv_modules'][str(id_module)])
233 module_dir=os.path.abspath(config.PATH_MODULES)+os.sep+str(id_module)
234 try:
235 shutil.rmtree(module_dir)
236 except:
237 return 1,u("""erreur de supression du répertoire du module""")
238 return 1,u('ok')
239
241 """modification d'un module
242 cette fonction prend en compte un dictionnaire qui indique les
243 champs à modifier et leur nouvelle valeur. l'application cliente
244 doit s'assurer que ces champs existent dans la base"""
245 self.parent.s_pool.check_mod_credential(cred_user, id_module)
246 if dico_modifs == {}:
247 return 1,u("""aucune modification demandée""")
248
249 if 'id' in dico_modifs.keys():
250 return 0,u("""l'identifiant ne peut pas être modifié""")
251
252 requete = ["update modules set "]
253 params = []
254 for cle in dico_modifs.keys():
255 requete.append(str(cle))
256 if cle == 'version':
257 requete.append("=%s, ")
258 params.append(int(dico_modifs[cle]))
259 else:
260 requete.append("=%s, ")
261 params.append(dico_modifs[cle])
262 string_fin=""" where id=%s"""
263 params.append(int(id_module))
264 query="".join(requete)[:-2]
265 query += string_fin
266 return self.dbpool.runOperation(query, params).addCallbacks(lambda x:(1,'ok'), db_client_failed)
267
269 """récupère un module précis dans la base ou tous les modules"""
270 if id_module :
271
272 query = """select id, libelle, version from modules where id = %s"""
273 return self.dbpool.runQuery(query, (int(id_module),)).addCallbacks(self._got_modules,db_client_failed,callbackArgs=[cred_user])
274 else :
275
276 query = """select id, libelle, version from modules order by version desc, libelle"""
277 return self.dbpool.runQuery(query).addCallbacks(self._got_modules,db_client_failed,callbackArgs=[cred_user])
278
280 """récupération du dictionnaire d'un module (valeurs par défaut)"""
281
282 try:
283 query = "select version from modules where id = %s"
284 except:
285 return 0, u("""donnez l'id d'un module (nombre entier)""")
286 return self.dbpool.runQuery(query, (int(id_module),)).addCallbacks(self._get_dico,db_client_failed,callbackArgs=[id_module, id_variante])
287
288 - def _get_dico(self,data,id_module,id_variante=None):
289
290 try:
291 version = int(data[0][0])
292 except:
293 version = 3
294
295 try:
296
297 if version == 1:
298
299 path_dico = os.path.join(os.path.abspath(config.PATH_ZEPHIR), 'modules', str(id_module), 'dictionnaire')
300
301 try:
302 fic = open(path_dico,'r')
303 except:
304 return 0, u("""dictionnaire non présent""")
305
306 lines = fic.readlines()
307 fic.close()
308 dictionnaire = [ unicode(line, 'ISO-8859-1').encode('UTF-8') for line in lines ]
309
310 if id_variante is not None:
311 dicos = os.path.join(os.path.abspath(config.PATH_ZEPHIR), 'modules', str(id_module), 'variantes', str(id_variante), 'dicos')
312 for nom_fic in os.listdir(dicos):
313 if nom_fic.endswith('.eol') or nom_fic.endswith('.xml'):
314
315 fic = open(os.path.join(dicos, nom_fic), 'r')
316 lines = fic.readlines()
317 fic.close()
318 dictionnaire.extend([ unicode(line, 'ISO-8859-1').encode('UTF-8') for line in lines ])
319
320
321 dic_complet=dico.DicoEole(dico_zephir=[dictionnaire])
322
323
324 if id_variante is not None:
325 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'
326 if os.path.isfile(path_dicovar):
327
328
329 f=file(path_dicovar)
330 lines = f.readlines()
331 f.close()
332 data = [ unicode(line, 'ISO-8859-1').encode('UTF-8') for line in lines ]
333
334 dic_actuel=dico.DicoEole(dico_zephir=[data]).ParseDico()
335 dico_final = {}
336
337 for variable, data in dic_complet.dictionnaire.items():
338
339 if dic_actuel.has_key(data[0]):
340 data[1] = dic_actuel[data[0]][0]
341 dico_final[variable]=data
342
343 dic_complet.dictionnaire = dico_final
344
345 dicos=[base64.encodestring(dic_complet.save("/dev/null"))]
346 else:
347
348
349 path_module = os.path.join(os.path.abspath(config.PATH_ZEPHIR), 'modules', str(id_module))
350 path_dico = os.path.join(path_module, 'dicos')
351
352 dict_dirs = [path_dico]
353 if id_variante is not None:
354
355 dict_dirs.append(os.path.join(path_module,'variantes',str(id_variante),'dicos'))
356 if os.path.isdir(os.path.join(path_module,'variantes',str(id_variante),'package')):
357 dict_dirs.append(os.path.join(path_module,'variantes',str(id_variante),'package'))
358
359 creole_version = config.CREOLE_VERSIONS[version]
360 dict_zeph = ZephirDict(dicos=dict_dirs, confdir=path_dico, mode='config', version=creole_version)
361 if creole_version == "creole2":
362 if os.path.isfile(os.path.join(path_module, 'module.eol')):
363 dict_zeph.dico.load_values(os.path.join(path_module,'module.eol'), check=False)
364
365 if id_variante is not None:
366 path_var = os.path.join(path_module, 'variantes', str(id_variante), 'dico.eol')
367 dict_zeph.dico.load_values(os.path.join(path_var), check=False)
368 elif creole_version == "creole3":
369
370 default_values = {}
371 path_mod = os.path.join(path_module, 'module.eol')
372 if os.path.isfile(path_mod):
373 try:
374 store = cjson.decode(file(path_mod).read(), all_unicode=True)
375 except cjson.DecodeError:
376 store = {}
377 default_values.update(store)
378
379 if id_variante is not None:
380 path_var = os.path.join(path_module, 'variantes', str(id_variante), 'dico.eol')
381 if os.path.isfile(path_var):
382 try:
383 store = cjson.decode(file(path_var).read(), all_unicode=True)
384 except cjson.DecodeError:
385 store = {}
386 default_values.update(store)
387 if default_values:
388
389 dict_zeph.init_from_zephir([str(default_values)])
390 dicos = dict_zeph.get_dict()
391 if dicos == None:
392 dicos = []
393 except Exception, e:
394 return 0, u(str(e))
395
396 return 1,u(dicos)
397
399 """récupération des libellés/familles des variables eole pour un module"""
400
401 try:
402 query = "select id,version from modules where id = %s"
403 except:
404 return 0, u("""donnez l'id d'un module (nombre entier)""")
405 return self.dbpool.runQuery(query, (int(id_module),)).addCallbacks(self._get_vars,db_client_failed)
406
408
409 try:
410 id_module = int(data[0][0])
411 except:
412 return 0, u("""module non trouvé""")
413 try:
414 version = int(data[0][1])
415 except:
416 version = 3
417
418 if version == 1:
419
420 creole_files = [os.path.abspath(config.PATH_ZEPHIR)+os.sep+'modules'+os.sep+str(id_module)+os.sep+'dictionnaire']
421
422 dicos = []
423 for dic in creole_files:
424 try:
425
426 fic = open(dic,'r')
427 lines = fic.readlines()
428 fic.close()
429 data = [ unicode(line, 'ISO-8859-1').encode('UTF-8') for line in lines ]
430
431 dicos.append(data)
432 except OSError:
433 pass
434 dict_zeph = ZephirDict(dicos=dicos, confdir='', mode='dico', version='creole1')
435 families = {}
436 else:
437
438
439 path_module = os.path.abspath(config.PATH_ZEPHIR)+os.sep+'modules'+os.sep+str(id_module)
440 path_dico = path_module+os.sep+'dicos'
441
442 dict_dirs = [path_dico]
443
444 creole_version = config.CREOLE_VERSIONS[version]
445 dict_zeph = ZephirDict(dicos=dict_dirs, confdir=path_dico, mode='config', version=creole_version)
446 families = {}
447 menu = dict_zeph.get_menu(True)
448 for family in menu:
449 for var in family[2]:
450 families[var] = family[0]
451
452
453 vars_dict = {}
454 try:
455 var_data = dict_zeph.get_first()
456 while 1:
457 if families.has_key(var_data[0]):
458 family = families[var_data[0]]
459 else:
460 family = ''
461 vars_dict[var_data[0]] = [var_data[2],family]
462 var_data = dict_zeph.get_next()
463 except:
464
465 pass
466
467 return 1,u(vars_dict)
468
469 - def xmlrpc_save_dico(self,cred_user,dico_b64,id_module,id_variante=None,pass_var=""):
470 """mise à jour du dictionnaire d'un module (valeurs par défaut)"""
471
472 self.parent.s_pool.check_mod_credential(cred_user, id_module)
473 if id_variante is not None:
474 self.parent.s_pool.check_var_credential(cred_user, id_variante)
475 query = "select modules.id, modules.libelle, modules.version, variantes.owner, variantes.passmd5 \
476 from modules,variantes where modules.id=%s and modules.id=variantes.module and variantes.id=%s"
477 return self.dbpool.runQuery(query, (int(id_module), int(id_variante))).addCallbacks(self._save_dico, db_client_failed, callbackArgs=[cred_user,dico_b64,id_variante,pass_var])
478 else:
479 query = """select id, libelle, version from modules where id=%s"""
480 return self.dbpool.runQuery(query, (int(id_module),)).addCallbacks(self._save_dico, db_client_failed, callbackArgs=[cred_user,dico_b64,id_variante,pass_var])
481
482 - def _save_dico(self,data,cred_user,dico_b64,id_variante=None,pass_var=""):
483 if data == []:
484 return 0,u("""module non retrouvé""")
485
486 id_module = data[0][0]
487 libelle = data[0][1]
488 try:
489 version = int(data[0][2])
490 except:
491 version = 3
492 if id_variante is not None:
493
494 owner = data[0][3]
495 passmd5 = data[0][4]
496 if owner != cred_user:
497
498 if passmd5 != pass_var and passmd5 not in [None,'', BLANK_MD5]:
499
500 return 0,u('mot de passe incorrect pour cette variante')
501
502 if version == 1:
503 try:
504
505 dico = base64.decodestring(dico_b64)
506
507 dico = unicode(dico,'UTF-8').encode('ISO-8859-1')
508
509 if id_variante is None:
510 path_dico = os.path.abspath(config.ROOT_DIR)+'/dictionnaires/dico-%s' % libelle
511 else:
512 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'
513 fic_zephir = open(path_dico,'w')
514 fic_zephir.write(dico)
515 fic_zephir.close()
516 except:
517 return 0,u("""erreur de sauvegarde du dictionnaire""")
518 else:
519 if id_variante is None:
520 path_dico = os.path.abspath(config.PATH_ZEPHIR)+os.sep+'modules'+os.sep+str(id_module)+os.sep+'module.eol'
521 else:
522 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'
523 creole_version = config.CREOLE_VERSIONS[version]
524 try:
525 values = eval(dico_b64[-1])
526 if creole_version == "creole3":
527 fic_zephir = file(path_dico, 'w')
528 fic_zephir.write(cjson.encode(values))
529 fic_zephir.close()
530 else:
531 parser = ConfigParser.ConfigParser()
532 parser._sections = values
533 fic_zephir = open(path_dico,'w')
534 parser.write(fic_zephir)
535 fic_zephir.close()
536 except:
537 return 0,u("""erreur de sauvegarde du dictionnaire""")
538
539 return 1,u('ok')
540
542 """renvoie la liste des dictionnaires d'un module.
543 utile pour les modules eole2 (fichier fixé pour les modules eole1)
544 """
545 self.parent.s_pool.check_mod_credential(cred_user, id_module)
546 query = "select id, version from modules where id=%s"
547 return self.dbpool.runQuery(query, (int(id_module),)).addCallbacks(self._get_mod_dict, db_client_failed)
548
550
551 id_module, version = data[0]
552 try:
553 version = int(version)
554 except:
555 version = 3
556 if version == 1:
557
558 return 1, []
559 try:
560 dest_dir=os.path.join(os.path.abspath(config.PATH_MODULES),str(id_module),"dicos")
561 content = []
562
563 for dict in os.listdir(dest_dir):
564 if dict.endswith('.xml'):
565 content.append(dict)
566 return 1, u(content)
567 except:
568 return 0,u("""erreur de parcours du répertoire des dictionnaires""")
569
571 """renvoie la liste des dictionnaires d'un module.
572 utile pour les modules eole2 (fichier fixé pour les modules eole1)
573 """
574
575 self.parent.s_pool.check_mod_credential(cred_user, id_module)
576 try:
577 fic_dest = os.path.join(os.path.abspath(config.PATH_MODULES),str(id_module),"dicos",dico_name)
578 assert os.path.isfile(fic_dest)
579 except:
580 return 0,u("""dictionnaire inexistant %s""" % dico_name)
581
582 try:
583 os.unlink(fic_dest)
584 return 1, "OK"
585 except:
586 return 0,u("""erreur lors de la suppression du dictionnaire""")
587
588
589
590
591
593 """formate les données lues dans la table variantes pour
594 l'envoyer à une application zephir (liste de dictionnaires)"""
595 l=[]
596 for variante in variantes:
597 owner = variante[3]
598 if owner == None:
599 owner = ""
600 try:
601 self.parent.s_pool.check_var_credential(cred_user, variante[0])
602 except ResourceAuthError:
603
604 continue
605 l.append({'id':variante[0],'module':variante[1],'libelle':variante[2],'owner':owner})
606 return 1,u(l)
607
608 - def xmlrpc_copy_variante(self,cred_user,module,id_var_src="",libelle="",passmd5="",keep_perms=False,id_var=""):
609 """Copie une variante existante sur une nouvelle variante"""
610
611 try:
612 var_src = int(id_var_src)
613 module = int(module)
614 if id_var == "":
615 assert libelle != ""
616 else:
617
618 id_var = int(id_var)
619 except:
620 return 0, u("""paramètres invalides""")
621
622
623 query = """select module,owner,passmd5 from variantes where id=%s"""
624 return self.dbpool.runQuery(query, (int(var_src),)).addCallbacks(self._copy_variante, db_client_failed,callbackArgs=[cred_user,var_src,libelle,module,passmd5,keep_perms,id_var])
625
626 - def _copy_variante(self,data,cred_user,var_src,libelle,module,passmd5,keep_perms,id_var):
627 """insertion de la nouvelle variante"""
628 try:
629 module_src = data[0][0]
630 if keep_perms and id_var == "":
631
632 cred_user = data[0][1]
633 passmd5 = data[0][2]
634 except:
635
636 return 0,u("""module d'origine non retrouvé dans la base""")
637
638 if id_var != "":
639
640 query = """select * from variantes where id=%s"""
641 return self.dbpool.runQuery(query, (int(id_var),)).addCallbacks(self._copy_variante3, db_client_failed,callbackArgs=[var_src,module_src,id_var,cred_user,passmd5])
642 else:
643
644 query = """insert into variantes (module,libelle,owner,passmd5) values (%s,%s,%s,%s)"""
645 params = (int(module), libelle, cred_user, passmd5)
646
647
648 return self.dbpool.runOperation(query, params).addCallbacks(self._copy_variante2, db_client_failed,callbackArgs=[var_src,module_src,libelle,module,id_var,cred_user,passmd5])
649
650 - def _copy_variante2(self,data,var_src,module_src,libelle,module,id_var,cred_user,passmd5):
651 """recherche de l'id de la variante créée"""
652
653 query = """select * from variantes where libelle=%s and module=%s"""
654 params = (libelle, int(module))
655 return self.dbpool.runQuery(query, params).addCallbacks(self._copy_variante3, db_client_failed,callbackArgs=[var_src,module_src,id_var,cred_user,passmd5])
656
657 - def _copy_variante3(self,data,var_src,module_src,id_var,cred_user,passmd5):
658 """copie l'arborescence de la variante source"""
659 try:
660 var_dest = data[0][0]
661 module = data[0][1]
662 libelle = data[0][2]
663 owner = data[0][3]
664 pass_var = data[0][4]
665 except:
666
667 return 0,u("""nouvelle variante non retrouvée dans la base""")
668 else:
669
670 rep_src=os.path.abspath(config.PATH_MODULES)+os.sep+str(module_src)+os.sep+'variantes'+os.sep+str(var_src)
671 rep_dest=os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+os.sep+'variantes'+os.sep+str(var_dest)
672 try:
673 if id_var == "":
674 if str(var_dest) not in self.parent.s_pool.stats['serv_variantes']:
675 self.parent.s_pool.stats['serv_variantes'][str(var_dest)] = 0
676 else:
677
678 if owner != cred_user:
679
680 if passmd5 != pass_var and pass_var not in [None,'', BLANK_MD5]:
681
682 return 0, u("""Mauvais mot de passe pour la variante de destination""")
683 shutil.rmtree(rep_dest)
684 shutil.copytree(rep_src,rep_dest)
685 except:
686 traceback.print_exc()
687 return 0,u("""erreur de copie de l'arborescence de la variante""")
688
689 query = """select id, libelle, version from modules where id = %s or id = %s"""
690 params = (int(module_src), int(module))
691 return self.dbpool.runQuery(query, params).addCallbacks(self._copy_variante4, db_client_failed,callbackArgs=[var_src, var_dest, module_src, module, id_var])
692
693 - def _copy_variante4(self, data, var_src, var_dest, module_src, module, id_var):
694 """stocke la concordance entre les variantes si nécessaire"""
695 if id_var == "":
696 version_src = version_dest = 0
697 libelle_src = libelle_dest = ""
698 try:
699 for mod in data:
700 if mod[0] == module_src:
701 version_src = int(mod[2])
702 libelle_src = mod[1][:mod[1].rindex("-")]
703 elif mod[0] == module:
704 version_dest = int(mod[2])
705 libelle_dest = mod[1][:mod[1].rindex("-")]
706 except:
707 log.msg('copie de variante : erreur lors de la recherche des version des modules sources et destination')
708
709 version_delta = version_dest - version_src
710 if libelle_src == libelle_dest and version_delta == 1:
711 query = """insert into migration_variantes (id_source, id_dest) values (%s,%s)"""
712 params = (int(var_src), int(var_dest))
713 return self.dbpool.runOperation(query, params).addCallbacks(lambda x:(1, var_dest), db_client_failed)
714 return 1, var_dest
715
717 """ajoute une variante à un module"""
718 self.parent.s_pool.check_mod_credential(cred_user, module)
719
720 if module and libelle:
721 query = """insert into variantes (module,libelle,owner,passmd5) values (%s,%s,%s,%s)"""
722 params = (int(module), libelle, cred_user, pass_var)
723
724
725 return self.dbpool.runOperation(query, params).addCallbacks(self._add_variante1, db_client_failed,callbackArgs=[libelle,module])
726 else:
727
728 return 0, u("""donnez un id de module et un libellé""")
729
731 """recherche de l'id de la variante créée"""
732
733 query = """select * from variantes where libelle ilike %s and module = %s"""
734 params = (libelle, int(module))
735 return self.dbpool.runQuery(query, params).addCallbacks(self._add_variante2,db_client_failed)
736
757
758
760 """suppression d'une variante de la base zephir"""
761 self.parent.s_pool.check_var_credential(cred_user, id_variante)
762 if id_variante:
763 query = """select * from variantes where id = %s"""
764
765 return self.dbpool.runQuery(query, (int(id_variante),)).addCallbacks(self._del_variante, db_client_failed)
766 else:
767 return 0,u("""donnez un identifiant de variante""")
768
770 """supprime la variante de la base de données"""
771 try:
772 id_variante = variante[0][0]
773 id_module = variante[0][1]
774 libelle = variante[0][2]
775 except:
776
777 return 0,u("""variante non trouvée dans la base""")
778 else:
779
780 if libelle == 'standard':
781 return 0, u("""la variante standard ne peut pas être supprimée""")
782
783 query = """delete from variantes where id = %s"""
784 return self.dbpool.runOperation(query, (int(id_variante),)).addCallbacks(self._del_variante2, db_client_failed,callbackArgs=[id_module,id_variante])
785
787 """supression de l'arborescence de la variante"""
788 del(self.parent.s_pool.stats['serv_variantes'][str(id_variante)])
789
790 variante_dir=os.path.abspath(config.PATH_MODULES)+os.sep+str(id_module)+os.sep+"variantes"+os.sep+str(id_variante)
791 try:
792 shutil.rmtree(variante_dir)
793 except:
794
795 return 0,u("""erreur de supression du répertoire de la variante""")
796 return 1, u('ok')
797
799 """ retourne la liste des fichiers personnalisés pour cette variante """
800 self.parent.s_pool.check_var_credential(cred_user, id_variante)
801 query = """select id,module from variantes where id = %s"""
802 return self.dbpool.runQuery(query, (int(id_variante),)).addCallbacks(self._fichiers_zephir,db_client_failed,callbackArgs=[show_details])
803
805 """recherche les fichiers liés à une variante"""
806 if data == []:
807 return 0,u("serveur inconnu de zephir")
808 else:
809 id_variante = int(data[0][0])
810 id_module = int(data[0][1])
811
812 variante_dir = os.path.abspath(config.PATH_ZEPHIR)+os.sep+'modules'+os.sep+str(id_module)+os.sep+'variantes'+os.sep+str(id_variante)
813
814 dico_res={}
815 try:
816
817 liste_dicos = []
818 liste_dicos_var = []
819 for fic in os.listdir(variante_dir+os.sep+'dicos'):
820 if fic.endswith('.eol') or fic.endswith('.xml'):
821 liste_dicos_var.append(fic)
822 dico_res['dicos_var'] = liste_dicos_var
823 except OSError:
824 dico_res['dicos_var'] = ['répertoire non trouvé !']
825 try:
826
827 dico_res['persos_var'] = (os.listdir(variante_dir+os.sep+'fichiers_perso'))
828 except OSError:
829 dico_res['persos_var'] = ['répertoire non trouvé !']
830 try:
831
832 dico_res['patchs_var'] = os.listdir(variante_dir+os.sep+'patchs')
833 except OSError:
834 dico_res['patchs_var'] = ['répertoire non trouvé !']
835 try:
836
837
838 fic = open(variante_dir+'/fichiers_zephir/fichiers_variante')
839 data = fic.read().split("\n")
840 fic.close()
841
842 liste_pkg_var = []
843 section_rpm = 0
844 for ligne in data:
845 ligne = ligne.strip()
846 if section_rpm == 1:
847
848 if not ligne.startswith('#') and ligne != '':
849
850 liste_pkg_var.append(ligne)
851 if ligne == '%%':
852 section_rpm = 1
853 dico_res['rpms_var'] = liste_pkg_var
854 except IOError:
855 dico_res['rpms_var'] = []
856 try:
857
858 liste_fic=[]
859 try:
860 f=open(variante_dir+os.sep+'fichiers_zephir/fichiers_variante')
861 old_content=f.read()
862 f.close()
863 fichiers=old_content.split('%%\n')[0]
864 except:
865 fichiers=""
866 for f_zeph in fichiers.split('\n'):
867 if f_zeph.strip().startswith("""/"""):
868 f_local = os.path.join(variante_dir,'fichiers_zephir',os.path.basename(f_zeph.strip()))
869 if show_details:
870 f_info = config.get_file_info(f_local)
871 liste_fic.append((f_zeph,f_info))
872 elif os.path.exists(f_local):
873 liste_fic.append(f_zeph)
874 dico_res['fichiers_var'] = liste_fic
875 except:
876 dico_res['fichiers_var'] = ['répertoire non trouvé !']
877 return 1,u(dico_res)
878
880 """renvoie les informations de permissions associées à un(des) fichier(s)
881 """
882
883 query = """select id,module from variantes where id=%s"""
884 return self.dbpool.runQuery(query, (int(id_variante),)).addCallbacks(self._get_variante_perms,db_client_failed,callbackArgs=[filepath])
885
887 """crée l'archive de la variante et la renvoie"""
888 if data != []:
889 id_variante = data[0][0]
890 id_module = data[0][1]
891
892 var_dir=os.path.abspath(config.PATH_MODULES)+os.sep+str(id_module)+os.sep+"variantes"+os.sep+str(id_variante)
893 try:
894 id_var = int(id_variante)
895
896 except (KeyError, ValueError):
897 return 0, u("""variante inconnue : %s""" % str(id_var))
898 else:
899 result = self.parent.s_pool.get_file_perms(var_dir, filepath)
900 return 1, u(result)
901
903 """supprime les informations de permissions associées à un(des) fichier(s)
904 """
905
906 query = """select id,module,owner,passmd5 from variantes where id=%s"""
907 return self.dbpool.runQuery(query, (int(id_variante),)).addCallbacks(self._del_variante_perms,db_client_failed,callbackArgs=[cred_user,filepath,pass_var])
908
910 """crée l'archive de la variante et la renvoie"""
911 if data != []:
912 id_variante = data[0][0]
913 id_module = data[0][1]
914 owner = data[0][2]
915 passmd5 = data[0][3]
916
917 if owner != cred_user:
918
919 if passmd5 != pass_var and passmd5 not in [None,'',BLANK_MD5]:
920
921 return 0,u('mot de passe incorrect pour cette variante')
922
923 var_dir=os.path.abspath(config.PATH_MODULES)+os.sep+str(id_module)+os.sep+"variantes"+os.sep+str(id_variante)
924 try:
925 id_var = int(id_variante)
926 except (KeyError, ValueError):
927 return 0, u("""variante inconnue : %s""" % str(id_var))
928 else:
929 result = self.parent.s_pool.del_file_perms(var_dir, filepath)
930 return 1, u(result)
931
933 """enregistre les informations de permissions associées à un(des) fichier(s)
934 @param rights: dictionnaire au format suviant : {'filepath':[mode,ownership]}
935 """
936
937 query = """select id,module,owner,passmd5 from variantes where id=%s"""
938 return self.dbpool.runQuery(query, (int(id_variante),)).addCallbacks(self._set_variante_perms,db_client_failed,callbackArgs=[cred_user,rights,pass_var])
939
941 """crée l'archive de la variante et la renvoie"""
942 if data != []:
943 id_variante = data[0][0]
944 id_module = data[0][1]
945 owner = data[0][2]
946 passmd5 = data[0][3]
947
948 if owner != cred_user:
949
950 if passmd5 != pass_var and passmd5 not in [None,'',BLANK_MD5]:
951
952 return 0,u('mot de passe incorrect pour cette variante')
953
954 var_dir=os.path.abspath(config.PATH_MODULES)+os.sep+str(id_module)+os.sep+"variantes"+os.sep+str(id_variante)
955 try:
956 id_var = int(id_variante)
957 except (KeyError, ValueError):
958 return 0, u("""variante inconnue : %s""" % str(id_var))
959 else:
960 res = self.parent.s_pool.set_file_perms(rights, var_dir)
961 if res:
962 return 1,"OK"
963 else:
964 return 0, u("""erreur d'enregistrement des permissions""")
965
967 """récupère la liste d'une variante (ou toutes)"""
968 if id_variante :
969 query = """select * from variantes where id=%s"""
970 return self.dbpool.runQuery(query, (int(id_variante),)).addCallbacks(self._got_variantes,db_client_failed,callbackArgs=[cred_user])
971 else :
972 query = """select * from variantes order by module desc, id desc"""
973 return self.dbpool.runQuery(query).addCallbacks(self._got_variantes,db_client_failed,callbackArgs=[cred_user])
974
976 """modification d'une variante
977 cette fonction prend en compte un dictionnaire qui indique les
978 champs à modifier et leur nouvelle valeur. l'application cliente
979 doit s'assurer que ces champs existent dans la base"""
980 self.parent.s_pool.check_var_credential(cred_user, id_variante)
981 defer_perms = self.parent.xmlrpc_get_permissions(cred_user, cred_user)
982 return defer_perms.addCallbacks(self._edit_variante, db_client_failed, callbackArgs=[cred_user,id_variante,dico_modifs,pass_var])
983
984 - def _edit_variante(self,permissions,cred_user,id_variante,dico_modifs,pass_var):
985
986 query = """select owner,passmd5 from variantes where id=%s"""
987 return self.dbpool.runQuery(query, (int(id_variante),)).addCallbacks(self._edit_variante2,db_client_failed,
988 callbackArgs=[cred_user,permissions,id_variante,dico_modifs,pass_var])
989
990 - def _edit_variante2(self,data,cred_user,permissions,id_variante,dico_modifs,pass_var):
991
992 if dico_modifs == {}:
993 return 1,u("""aucune modification demandée""")
994 owner = data[0][0]
995 passmd5 = data[0][1]
996 is_admin = False
997 if permissions[0] == 1 and 4 in permissions[1]:
998 is_admin = True
999
1000 if owner != cred_user:
1001
1002 if passmd5 != pass_var and passmd5 not in [None,'',BLANK_MD5]:
1003
1004 return 0,u('mot de passe incorrect pour cette variante')
1005 if ('id' in dico_modifs.keys()) or ('module' in dico_modifs.keys()):
1006 return 0,u("""l'identifiant et le module ne peuvent pas être modifiés""")
1007 if ('owner' in dico_modifs.keys()) or ('passmd5' in dico_modifs.keys()):
1008
1009
1010 if cred_user != owner and not is_admin:
1011 return 0,u("""modification du propriétaire ou mot de passe interdits""")
1012 if 'owner' in dico_modifs.keys():
1013 log.msg("nouveau propriétaire pour la variante %s : %s" % (str(id_variante), dico_modifs['owner']))
1014 if 'passmd5' in dico_modifs.keys():
1015 log.msg("changement du mot de passe de la variante %s" % str(id_variante))
1016
1017 requete = ["update variantes set "]
1018 params = []
1019 for cle in dico_modifs.keys():
1020 requete.append(str(cle))
1021 requete.append("=%s, ")
1022 params.append(str(dico_modifs[cle]))
1023 string_fin=""" where id=%s"""
1024 params.append(int(id_variante))
1025 query = "".join(requete)[:-2]
1026 query += string_fin
1027 return self.dbpool.runOperation(query, params).addCallbacks(lambda x:(1,'ok'), db_client_failed)
1028
1030 """récupère la liste des variantes d'un module et des variantes de migration définies
1031 """
1032 try:
1033 id_module = int(id_module)
1034 except:
1035 return 0,u("identifiant de module invalide")
1036 self.parent.s_pool.check_mod_credential(cred_user, id_module)
1037
1038 query = """select id, libelle, version from modules"""
1039 return self.dbpool.runQuery(query).addCallbacks(self._get_migration_infos,db_client_failed,callbackArgs=[id_module])
1040
1042
1043 mod_src_lib = ""
1044 mod_src_version = 0
1045 info_modules = {}
1046 for module in data:
1047 if module[0] == id_module:
1048 mod_src_lib = module[1]
1049 mod_src_version = int(module[2])
1050 break
1051 migration_infos = {}
1052 if mod_src_version in config.allowed_migrations:
1053
1054 return 1, []
1055 elif mod_src_version > 1:
1056 mod_src_name = mod_src_lib[:mod_src_lib.rindex('-')]
1057
1058 allowed_upgrades = [mod_src_version+1]
1059 if mod_src_name in config.allowed_upgrades and mod_src_version in config.allowed_upgrades[mod_src_name]:
1060 allowed_upgrades.extend(config.allowed_upgrades[mod_src_name][mod_src_version])
1061 for module in data:
1062 mod_name = module[1][:module[1].rindex('-')]
1063 mod_version = int(module[2])
1064 if mod_name == mod_src_name:
1065 if mod_version in allowed_upgrades:
1066 info_modules[module[0]] = [module[1],int(module[2])]
1067 migration_infos[mod_version] = [[],[]]
1068 query="""select modules.version, id_source, id_dest, var_dst.module from migration_variantes, modules, variantes as var_dst, variantes as var_src where id_source=var_src.id and var_src.module=%s and var_dst.id=id_dest and modules.id = var_dst.module"""
1069 return self.dbpool.runQuery(query, (int(id_module),)).addCallbacks(self._get_migration_infos2,db_client_failed,callbackArgs=[id_module, migration_infos, info_modules])
1070 else:
1071 return 0,u("module inexistant dans la base")
1072
1074
1075 for var_migration in data:
1076 if var_migration[0] in migration_infos:
1077 migration_infos[var_migration[0]][1].append([var_migration[1], var_migration[2]])
1078 query = """select id, module from variantes"""
1079 return self.dbpool.runQuery(query).addCallbacks(self._get_migration_infos3, db_client_failed,callbackArgs=[id_module, migration_infos, info_modules])
1080
1082
1083 for id_var, id_mod in data:
1084
1085 if id_mod in info_modules:
1086 vers_mod = info_modules[id_mod][1]
1087
1088 if vers_mod in migration_infos:
1089
1090 migration_infos[vers_mod][0].append(id_var)
1091 result = []
1092 for vers, data in migration_infos.items():
1093 result.append((vers, data[0], data[1]))
1094 return 1, result
1095
1097 """sauvegarde les équivalences d'une variable pour upgrade_auto
1098 """
1099 try:
1100 var_src = int(var_src)
1101 var_dest = []
1102 if type(var_migr) != list:
1103 var_migr = [var_migr]
1104 for var in var_migr:
1105 var_dest.append(int(var))
1106 except:
1107 return 0,u("identifiant de variante invalide")
1108 self.parent.s_pool.check_var_credential(cred_user, var_src)
1109
1110 query = """delete from migration_variantes where id_source=%s"""
1111 return self.dbpool.runOperation(query, (int(var_src),)).addCallbacks(self._variantes_upgrade2, db_client_failed, callbackArgs=[var_src, var_dest])
1112
1114 """sauvegarde les équivalences d'une variable pour upgrade_auto
1115 """
1116 if var_dest != []:
1117 params = []
1118 inserts = []
1119 for dst in var_dest:
1120 inserts.append('(%s,%s)')
1121 params.extend([int(var_src), int(dst)])
1122 query = """insert into migration_variantes (id_source, id_dest) values %s""" % ", ".join(inserts)
1123 return self.dbpool.runOperation(query, params).addCallbacks(lambda x:(1,'ok'), db_client_failed)
1124 else:
1125 return 1, 'ok'
1126
1127 - def xmlrpc_add_files(self,cred_user,id_variante,dico_files,passwd="",encode=False):
1128 """ajoute des fichiers, patchs, dictionnaires à une variante
1129 """
1130 self.parent.s_pool.check_var_credential(cred_user, id_variante)
1131 query="select modules.version,variantes.id,variantes.module,variantes.owner,variantes.passmd5 from variantes,modules where variantes.id=%s and modules.id=variantes.module"
1132 return self.dbpool.runQuery(query, (int(id_variante),)).addCallbacks(self._add_files,db_client_failed,callbackArgs=[dico_files,cred_user,passwd,encode])
1133
1134 - def _add_files(self,data,dico_files,cred_user,passwd,encode):
1135 """ajoute des fichiers, patchs, dictionnaires,rpms à une variante
1136 """
1137 mod_version = data[0][0]
1138 try:
1139 mod_version = int(mod_version)
1140 except:
1141 mod_version = 3
1142 id_variante = data[0][1]
1143 id_module = data[0][2]
1144 owner = data[0][3]
1145 pass_var = data[0][4]
1146
1147 if owner != cred_user:
1148
1149 if passwd != pass_var and pass_var not in [None,'',BLANK_MD5]:
1150
1151 return 0,u('mot de passe incorrect pour cette variante')
1152
1153 dest_dir=os.path.abspath(config.PATH_MODULES)+os.sep+str(id_module)+os.sep+"variantes"+os.sep+str(id_variante)
1154
1155 if mod_version == 1 and encode == True:
1156 for type_f, files in dico_files.items():
1157 if type_f in ['dicos_var','patchs_var','persos_var','fichiers_var']:
1158 encoded_files = []
1159 for fichier in dico_files[type_f]:
1160 content = unicode(base64.decodestring(fichier[1]),config.charset).encode('ISO-8859-1')
1161 localpath = ""
1162 if len(fichier) == 3:
1163 localpath = fichier[2]
1164 encoded_files.append([fichier[0], base64.encodestring(content),localpath])
1165 dico_files[type_f] = encoded_files
1166
1167 liste_remove = []
1168 if os.path.isfile(dest_dir+os.sep+'fichiers_zephir/removed'):
1169 f_rem = open(dest_dir+os.sep+'fichiers_zephir/removed')
1170 for fic in f_rem.read().strip().split('\n'):
1171 liste_remove.append(fic)
1172 f_rem.close()
1173 def check_removed(nom_dest):
1174
1175 if nom_dest in liste_remove:
1176 liste_remove.remove(nom_dest)
1177 f_rem = open(dest_dir+os.sep+'fichiers_zephir/removed', 'w')
1178 f_rem.write('\n'.join(liste_remove))
1179 f_rem.close()
1180
1181 if dico_files.has_key('rpms_var'):
1182 use_pool = self.parent.dictpool.check_module(id_module)
1183 if use_pool:
1184
1185 denied = self.parent.dictpool.list_module(id_module, False)
1186 denied = set([paq_name for paq_name in denied if not paq_name.endswith('.xml')])
1187
1188 bad_paqs = denied.intersection(set(dico_files['rpms_var']))
1189 if bad_paqs:
1190 return 0, u("""paquets déjà référencés au niveau du module : %s""" % ', '.join(bad_paqs))
1191
1192
1193 for dico in dico_files['dicos_var']:
1194 try:
1195 if dico[0] != "":
1196 f=open(dest_dir+os.sep+'dicos'+os.sep+os.path.basename(dico[0].replace("\\","/")),'w')
1197 f.write(base64.decodestring(dico[1]))
1198 f.close()
1199 except:
1200 return 0,u("erreur de sauvegarde de %s" % dico)
1201 for template in dico_files['persos_var']:
1202 try:
1203 if template[0] != "":
1204 f=open(dest_dir+os.sep+'fichiers_perso'+os.sep+os.path.basename(template[0].replace("\\","/")),'w')
1205 f.write(base64.decodestring(template[1]))
1206 f.close()
1207 check_removed(os.path.join('fichiers_perso', template[0].replace("\\","/")))
1208 except:
1209 return 0,u("erreur de sauvegarde de %s" % template)
1210 for patch in dico_files['patchs_var']:
1211 try:
1212 if patch[0] != "":
1213 f=open(dest_dir+os.sep+'patchs'+os.sep+os.path.basename(patch[0].replace("\\","/")),'w')
1214 f.write(base64.decodestring(patch[1]))
1215 f.close()
1216 except:
1217 return 0,u("erreur de sauvegarde de %s" % patch)
1218
1219 try:
1220 f=open(dest_dir+os.sep+'fichiers_zephir/fichiers_variante')
1221 old_content=f.read()
1222 f.close()
1223 fichiers=old_content.split('%%\n')[0]
1224 rpms=old_content.split('%%\n')[1]
1225 except:
1226 fichiers="""# section 1
1227 # liste des fichiers à sauvegarder
1228 # (ne pas modifier sauf pour créer ou mettre à jour la variante)"""
1229 rpms="""# section 2
1230 # inscrire les noms des paquetages qui seront installés à la mise à jour du serveur
1231 # (ils doivent être présents sur le serveur de mise à jour)"""
1232
1233 for fichier in dico_files['fichiers_var']:
1234
1235 localpath = ""
1236 if len(fichier) == 3:
1237 localpath = fichier[2]
1238
1239 conteneur = ""
1240 if '::' in fichier[0]:
1241 fic_path, conteneur = fichier[0].split('::')
1242 else:
1243 fic_path = fichier[0]
1244
1245 nom_fic = fic_path.replace("\\","/")
1246
1247 if fic_path.endswith('/'):
1248 nom_fic = fic_path[:-1]
1249 if fic_path.endswith("\\"):
1250 nom_fic = fic_path[:-2]
1251 if conteneur:
1252 nom_final = "%s::%s" % (nom_fic, conteneur)
1253 else:
1254 nom_final = nom_fic
1255 check_removed(nom_final)
1256
1257 if nom_final not in fichiers.split('\n') and localpath == "":
1258 fichiers = fichiers.strip() + '\n' + nom_final +'\n'
1259
1260 try:
1261 if nom_fic != "":
1262 if localpath == "":
1263 f=open(os.path.join(dest_dir,'fichiers_zephir',os.path.basename(nom_final)),'w')
1264 else:
1265 f=open(os.path.join(dest_dir,localpath,os.path.basename(nom_final)),'w')
1266 f.write(base64.decodestring(fichier[1]))
1267 f.close()
1268 except:
1269 return 0,u("erreur de sauvegarde de %s" % fichier)
1270
1271
1272 if dico_files.has_key('rpms_var'):
1273 for rpm in dico_files['rpms_var']:
1274
1275 if rpm not in rpms.split('\n'):
1276 rpms = rpms.strip() + '\n' + rpm +'\n'
1277
1278 f=open(dest_dir+os.sep+'fichiers_zephir/fichiers_variante','w')
1279 f.write(fichiers+"%%\n"+rpms)
1280 f.close()
1281 if self.parent.dictpool.check_module(id_module):
1282
1283
1284 self.parent.dictpool.sync_variante_paqs(id_variante)
1285 return 1,u("ok")
1286
1287 - def xmlrpc_del_files(self,cred_user,id_variante,dico_files,remove=False,passwd=None):
1288 """suppression de fichiers, patchs, dictionnaires d'une variante
1289 """
1290 self.parent.s_pool.check_var_credential(cred_user, id_variante)
1291 query = "select id,module,owner,passmd5 from variantes where id=%s"
1292 return self.dbpool.runQuery(query, (int(id_variante),)).addCallbacks(self._del_files,db_client_failed,callbackArgs=[dico_files,cred_user,remove,passwd])
1293
1294 - def _del_files(self,data,dico_files,cred_user,remove,passwd):
1295 """supression de fichiers, patchs, dictionnaires,rpms d'une variante
1296 """
1297 id_variante = data[0][0]
1298 id_module = data[0][1]
1299 owner = data[0][2]
1300 pass_var = data[0][3]
1301
1302 if owner != cred_user:
1303
1304 if passwd != pass_var and pass_var not in [None,'',BLANK_MD5]:
1305
1306 return 0,u('mot de passe incorrect pour cette variante')
1307
1308 dest_dir=os.path.abspath(config.PATH_MODULES)+os.sep+str(id_module)+os.sep+"variantes"+os.sep+str(id_variante)
1309 if remove:
1310 liste_remove = []
1311
1312 if os.path.isfile(dest_dir+os.sep+'fichiers_zephir/removed'):
1313 f_rem = open(dest_dir+os.sep+'fichiers_zephir/removed')
1314 for fic in f_rem.read().strip().split('\n'):
1315 liste_remove.append(fic)
1316 f_rem.close()
1317
1318 for dico in dico_files['dicos_var']:
1319 try:
1320 if dico != "":
1321 os.unlink(dest_dir+os.sep+'dicos'+os.sep+dico)
1322 except:
1323 return 0,u("erreur de suppression de %s" % dico)
1324 for template in dico_files['persos_var']:
1325 try:
1326 if template != "":
1327 os.unlink(dest_dir+os.sep+'fichiers_perso'+os.sep+template)
1328 except:
1329 return 0,u("erreur de supression de %s" % template)
1330
1331 self.parent.s_pool.del_file_perms(dest_dir,'fichiers_perso'+os.sep+template)
1332
1333
1334 if remove:
1335 fic_sup = os.path.join('fichiers_perso', template)
1336 if fic_sup not in liste_remove:
1337 liste_remove.append(fic_sup)
1338
1339 for patch in dico_files['patchs_var']:
1340 try:
1341 if patch != "":
1342 os.unlink(dest_dir+os.sep+'patchs'+os.sep+patch)
1343 except:
1344 return 0,u("erreur de suppression de %s" % patch)
1345
1346 try:
1347 f=open(dest_dir+os.sep+'fichiers_zephir/fichiers_variante')
1348 old_content=f.read()
1349 f.close()
1350 fichiers=old_content.split('%%\n')[0]
1351 rpms=old_content.split('%%\n')[1]
1352 except:
1353 fichiers="""# section 1
1354 # liste des fichiers à sauvegarder pour la variante
1355 # (ne pas modifier sauf pour créer ou mettre à jour la variante)"""
1356 rpms="""# section 2
1357 # inscrire les noms des paquetages qui seront installés à la mise à jour du serveur
1358 # (ils doivent être présents sur le serveur de mise à jour)"""
1359 liste=fichiers.split('\n')
1360
1361 for fichier in dico_files['fichiers_var']:
1362 localpath = "fichiers_zephir"
1363 if type(fichier) in (list, tuple) and len(fichier) == 2:
1364 localpath = fichier[1]
1365 fichier = fichier[0]
1366
1367 if fichier in liste:
1368 liste.remove(fichier)
1369 fichiers = "\n".join(liste)
1370 fic_path = os.path.join(dest_dir, localpath, os.path.basename(fichier.replace("\\","/")))
1371
1372 try:
1373 if fichier != "":
1374 if os.path.isdir(fic_path):
1375 shutil.rmtree(fic_path)
1376 elif os.path.isfile(fic_path):
1377 os.unlink(fic_path)
1378 except:
1379 f=open(dest_dir+os.sep+'fichiers_zephir/fichiers_variante','w')
1380 f.write(fichiers+"%%\n"+rpms)
1381 f.close()
1382 return 0,u("erreur de suppression de %s" % fichier)
1383
1384 fic_sup = os.path.join(localpath,os.path.basename(fichier.replace("\\","/")))
1385 self.parent.s_pool.del_file_perms(dest_dir,fic_sup,True)
1386
1387
1388 if remove:
1389 fic_rem = fichier.replace("\\","/")
1390 if fic_rem not in liste_remove:
1391 liste_remove.append(fic_rem)
1392
1393
1394 for rpm in dico_files['rpms_var']:
1395
1396 liste=rpms.split('\n')
1397 if rpm in liste:
1398 liste.remove(rpm)
1399 rpms = "\n".join(liste)
1400 else:
1401 f=open(dest_dir+os.sep+'fichiers_zephir/fichiers_variante','w')
1402 f.write(fichiers+"%%\n"+rpms)
1403 f.close()
1404 return 0,u("rpm non trouvé dans la liste : %s" % rpm)
1405
1406 f=open(dest_dir+os.sep+'fichiers_zephir/fichiers_variante','w')
1407 f.write(fichiers+"%%\n"+rpms)
1408 f.close()
1409 if remove and liste_remove:
1410
1411 f=open(dest_dir+os.sep+'fichiers_zephir/removed', 'w')
1412 f.write("\n".join(liste_remove))
1413 f.close()
1414
1415 return 1,u("ok")
1416
1418 """renvoie le contenu d'un fichier de variante"""
1419
1420 self.parent.s_pool.check_var_credential(cred_user, id_var)
1421 query="select variantes.id,variantes.module,modules.version from variantes,modules where variantes.id=%s and modules.id=variantes.module" % id_var
1422 return self.dbpool.runQuery(query, (int(id_var),)).addCallbacks(self._get_var_file,db_client_failed,callbackArgs=[path,show_details])
1423
1425 id_var = data[0][0]
1426 id_module = data[0][1]
1427 mod_version = data[0][2]
1428 try:
1429 mod_version = int(mod_version)
1430 except:
1431 mod_version = 3
1432 try:
1433 dest_dir=os.path.abspath(config.PATH_MODULES)+os.sep+str(id_module)+os.sep+"variantes"+os.sep+str(id_var)
1434 except:
1435 return 0,u("""lecture du fichier: paramètres non valides""")
1436
1437 try:
1438
1439 if os.path.isdir(dest_dir + os.sep + path):
1440 dirfiles = os.listdir(dest_dir + os.sep + path)
1441 content = []
1442 if show_details:
1443 for f in dirfiles:
1444 f_local = os.path.join(dest_dir,path,f)
1445 f_info = config.get_file_info(f_local)
1446 content.append((f,f_info))
1447 else:
1448 content = dirfiles
1449 return 1, u(content)
1450 else:
1451 if istextfile(dest_dir + os.sep + path):
1452 f=file(dest_dir + os.sep + path)
1453 content=f.read()
1454 f.close()
1455
1456 if mod_version == 1:
1457 try:
1458 content = unicode(content,'ISO-8859-1').encode(config.charset)
1459 except:
1460
1461 log.msg("echec d'encoding du fichier %s provenant d'un serveur eole1" % path)
1462 content = base64.encodestring(content)
1463 else:
1464 content = "BINARY"
1465 return 1, content
1466 except:
1467 return 0,u("""erreur de lecture du fichier""")
1468
1470 """envoie le contenu d'une variante sur un autre zephir"""
1471
1472 query = """select id,module from variantes where id=%s"""
1473 return self.dbpool.runQuery(query, (int(id_variante),)).addCallbacks(self._export_variante,db_client_failed)
1474
1476 """crée l'archive de la variante et le renvoie"""
1477 if data != []:
1478 id_variante = data[0][0]
1479 id_module = data[0][1]
1480
1481 parent_dir=os.path.abspath(config.PATH_MODULES)+os.sep+str(id_module)+os.sep+"variantes"
1482 var_dir=parent_dir+os.sep+str(id_variante)
1483
1484 archive=str(time.time())
1485 if os.path.isdir(var_dir):
1486
1487 cmd_tar = ['cd ',var_dir,';','tar','-chzf','/tmp/'+archive+'.tgz','*']
1488 cmd_tar.append('2>&1 >/dev/null')
1489
1490 res=os.system(" ".join(cmd_tar))
1491 if res != 0:
1492 return 0, u("""erreur de création de l'archive %s.tgz dans /tmp""" % (archive))
1493 else:
1494
1495 cmd_checksum = """cd /tmp/; md5sum -b %s.tgz > %s.md5""" % (archive,archive)
1496 res=os.system(cmd_checksum)
1497
1498 try:
1499
1500 f = open('/tmp'+os.sep+archive+'.md5')
1501 data1 = f.read()
1502 f.close()
1503 os.unlink('/tmp'+os.sep+archive+'.md5')
1504
1505 f = open('/tmp'+os.sep+archive+'.tgz')
1506 data2 = f.read()
1507 f.close()
1508 os.unlink('/tmp'+os.sep+archive+'.tgz')
1509 return 1,u([archive,base64.encodestring(data1),base64.encodestring(data2)])
1510 except Exception, e:
1511 return 0,u("""erreur lors de l'envoi de l'archive : %s""" % str(e))
1512 else:
1513 return 0, u("""répertoire %s introuvable""" % var_dir)
1514 else:
1515 return 0, u("""variante inexistante""")
1516
1517 - def xmlrpc_import_variante(self,cred_user,pwd_var,id_local,id_distant,zephir_distant,login_distant,pwd_distant):
1518 """récupère le contenu d'une variante sur un autre zephir"""
1519
1520 z=EoleProxy("https://%s:%s@%s:%s" % (login_distant,pwd_distant,zephir_distant,config.PORT_ZEPHIR))
1521
1522 try:
1523 res=z.modules.get_variante(id_distant)
1524 except:
1525 return 0,u("""permissions insuffisantes""")
1526 if res[0] == 0:
1527 return 0,u("""erreur lors de la recherche de la variante d'origine""")
1528
1529
1530 query = """select id, module, owner, passmd5 from variantes where id=%s"""
1531 return self.dbpool.runQuery(query, (int(id_local),)).addCallbacks(self._import_variante,db_client_failed,callbackArgs=[z,id_distant,cred_user,pwd_var])
1532
1534 """demande l'envoi de l'archive et met en place les fichiers"""
1535 if data == []:
1536 return 0, u("""variante locale non trouvée""")
1537 else:
1538 id_variante = data[0][0]
1539 id_module = data[0][1]
1540 owner = data[0][2]
1541 passmd5 = data[0][3]
1542
1543 if owner != cred_user and pwd_var != passmd5:
1544 return 0,u("""mauvais mot de passe de variante""")
1545 else:
1546
1547 parent_dir=os.path.abspath(config.PATH_MODULES)+os.sep+str(id_module)+os.sep+"variantes"
1548 var_dir = parent_dir+os.sep+str(id_variante)
1549
1550 if not os.path.exists(var_dir):
1551 return 0,u("""répertoire de la variante de destination non trouvé""")
1552
1553 res=proxy.modules.export_variante(id_distant)
1554 if res[0]==0:
1555 return 0,u("""erreur lors de la récupération de la variante""")
1556 else:
1557
1558 archive=res[1][0]
1559
1560 var_data=base64.decodestring(res[1][1])
1561
1562 md5_data=base64.decodestring(res[1][2])
1563 try:
1564
1565 shutil.rmtree(var_dir)
1566
1567 os.makedirs(var_dir)
1568
1569 f=open(var_dir+os.sep+archive+'.tgz','w')
1570 f.write(md5_data)
1571 f.close()
1572 f=open(var_dir+os.sep+archive+'.md5','w')
1573 f.write(var_data)
1574 f.close()
1575
1576 cmd_md5 = """cd %s; md5sum -c %s.md5 2>&1 > /dev/null""" % (var_dir,archive)
1577 res=os.system(cmd_md5)
1578 if res != 0:
1579 return 0,u("""archive corrompue""")
1580
1581 cmd_tar = """cd %s ; tar -xzf %s.tgz > /dev/null""" % (var_dir,archive)
1582 res=os.system(cmd_tar)
1583 if res != 0:
1584 return 0,u("""erreur de décompression de l'archive""")
1585
1586 os.unlink(var_dir+os.sep+archive+'.tgz')
1587 os.unlink(var_dir+os.sep+archive+'.md5')
1588 except Exception, e:
1589 return 0,u("""erreur de mise en place des fichiers de la variante : %s""" % str(e))
1590
1591 return 1,u("ok")
1592