Package zephir :: Package backend :: Module modules_rpc
[frames] | no frames]

Source Code for Module zephir.backend.modules_rpc

   1  # -*- coding: UTF-8 -*- 
   2  ########################################################################### 
   3  # Eole NG - 2007 
   4  # Copyright Pole de Competence Eole  (Ministere Education - Academie Dijon) 
   5  # Licence CeCill  cf /root/LicenceEole.txt 
   6  # eole@ac-dijon.fr 
   7  # 
   8  # modules_rpc.py 
   9  # 
  10  # fonctions xmlrpc pour la gestion des modules dans Zephir 
  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  # import relatifs aux tables 
  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   
32 -class RPCModules(XMLRPC):
33 """serveur XMLRPC zephir pour la gestion des modules Eole 34 """ 35
36 - def __init__(self,parent):
37 self.dbpool = db_connect() 38 self.dbpool.noisy = 0 39 self.parent = parent 40 # mise à jour des modules si besoin 41 XMLRPC.__init__(self)
42
43 - def startup(self):
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
50 - def stop(self):
51 if self.old_obs: 52 log.removeObserver(log.theLogPublisher.observers[0]) 53 log.addObserver(self.old_obs)
54
55 - def xmlrpc_update_modules(self,cred_user=''):
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 # Erreur de lecture des modules 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 # on recrée automatiquement les modules manquants, en dehors des modules Eole 1.X 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
82 - def _update_module(self, result, new_modules):
83 # log de la création des modules 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 # mise à jour des données du pool de dictionnaires 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
97 - def _got_modules(self,modules,cred_user):
98 """Récupération de la table module depuis le backend 99 """ 100 l=[] 101 for module in modules: 102 try: 103 self.parent.s_pool.check_mod_credential(cred_user, module[0]) 104 except ResourceAuthError: 105 # non autorisé : module suivant 106 continue 107 if module[2] == None: 108 version = 1 109 else: 110 version = module[2] 111 l.append({'id':module[0],'libelle':module[1],'version':version}) 112 return 1,u(l)
113 114 ############################## 115 ## gestion de la table modules 116 ############################## 117 118
119 - def xmlrpc_add_module(self, cred_user, libelle, version=3, auto=False):
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 # on vérifie que les données obligatoires sont remplies 125 if libelle: 126 query = """insert into modules (libelle, version) values (%s,%s)""" 127 params = (libelle, int(version)) 128 # on effectue l'insertion (l'existence est à tester dans l'application cliente) 129 return self.dbpool.runOperation(query, params).addCallbacks(self._add_module1,db_client_failed,callbackArgs=[libelle, version, auto]) 130 else: 131 # des attributs manquent 132 return 0, u("""donnez un libellé""")
133
134 - def _add_module1(self, resultat, libelle, version, auto):
135 """récupère l'id du module créé""" 136 # requête pour récupérer l'id 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
140 - def _add_module2(self, row, libelle, version, auto):
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 # on crée la variante standard du module 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
156 - def _add_module4(self,row,libelle,version,auto):
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 # on créé l'arborescence pour le module 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 # lien du(des) dictionnaire(s) 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 # module eole 2 174 dico_module=os.path.abspath(config.ROOT_DIR)+'/dictionnaires/%s' % libelle 175 if os.path.isdir(dico_module): 176 # modules de base eole (ancienne méthode de gestion des dicos) 177 os.system('ln -s %s %s' % (dico_module, os.path.join(module_dir,'dicos'))) 178 # création d'un fichier de valeurs par défaut 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 # on crée la variante par défaut (module standard) 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 # aucun répertoire créé 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 # mise à jour des statistiques 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 # mise à jour du pool de dictionnaires si lancé par un utilisateur 204 if not auto: 205 self.parent.dictpool.update_data() 206 return 1, u(id_module)
207
208 - def xmlrpc_del_module(self,cred_user,id_module):
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 # suppression des variantes dans la base de données 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
218 - def _del_module(self,retour,id_module):
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
223 - def _del_module1(self,retour,id_module):
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
228 - def _del_module2(self,retour,id_module):
229 """supprime l'arborescence du module dans l'arborescence zephir""" 230 # mise à jour des statistiques 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
240 - def xmlrpc_edit_module(self,cred_user,id_module,dico_modifs):
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 # on vérifie que l'identifiant n'est pas modifié 249 if 'id' in dico_modifs.keys(): 250 return 0,u("""l'identifiant ne peut pas être modifié""") 251 # construction de la requête SQL de modification 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
268 - def xmlrpc_get_module(self,cred_user, id_module=None):
269 """récupère un module précis dans la base ou tous les modules""" 270 if id_module : 271 # on récupère le module demandé 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 # sinon on renvoie tous les modules 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
279 - def xmlrpc_get_dico(self,cred_user,id_module,id_variante=None):
280 """récupération du dictionnaire d'un module (valeurs par défaut)""" 281 # recherche du répertoire ou le dictionnaire est stocké 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 # détection version de créole 290 try: 291 version = int(data[0][0]) 292 except: 293 version = 3 294 295 try: 296 # dictionnaire de base du module 297 if version == 1: 298 # module Eole1 299 path_dico = os.path.join(os.path.abspath(config.PATH_ZEPHIR), 'modules', str(id_module), 'dictionnaire') 300 # envoi des fichiers de configuration au programme de saisie 301 try: 302 fic = open(path_dico,'r') 303 except: 304 return 0, u("""dictionnaire non présent""") 305 # dictionnaire du module 306 lines = fic.readlines() 307 fic.close() 308 dictionnaire = [ unicode(line, 'ISO-8859-1').encode('UTF-8') for line in lines ] 309 # dictionnaires additionnels 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 # ajout d'un dictionnaire 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 # dictionnaire complet (dictionnaire module + dico locaux) 321 dic_complet=dico.DicoEole(dico_zephir=[dictionnaire]) 322 323 # si un dico.eol existait déjà, on reprend les anciennes valeurs 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 # on instancie un dictionnaire depuis dico.eol 328 # et un autre avec le dictionnaire complet 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 # dictionnaire des valeurs actuelles 334 dic_actuel=dico.DicoEole(dico_zephir=[data]).ParseDico() 335 dico_final = {} 336 # on réinsère les données existantes dans le dictionnaire 337 for variable, data in dic_complet.dictionnaire.items(): 338 # si la variable existait déjà, on reprend sa valeur 339 if dic_actuel.has_key(data[0]): 340 data[1] = dic_actuel[data[0]][0] 341 dico_final[variable]=data 342 # on remet le dictionnaire modifié en place dans dico_serveur 343 dic_complet.dictionnaire = dico_final 344 345 dicos=[base64.encodestring(dic_complet.save("/dev/null"))] 346 else: 347 # version creole2 348 # chargement de configuration pour un serveur Eole2 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 # définition des dictionnaires à charger 352 dict_dirs = [path_dico] 353 if id_variante is not None: 354 # dictionnaires de la variante si besoin 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 # création de l'objet ZephirDict et lecture des valeurs existantes 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 # traitement de la variante si demandé 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 # creole3 : on initialise un 'store' JSON avec les valeurs définies au niveau module/variante 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 # traitement de la variante si demandé 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 # chargement des valeurs 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
398 - def xmlrpc_get_vars(self,cred_user,id_module):
399 """récupération des libellés/familles des variables eole pour un module""" 400 # recherche du répertoire ou le dictionnaire est stocké 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
407 - def _get_vars(self,data):
408 # détection version de créole 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 # dictionnaire de base du module 418 if version == 1: 419 # module Eole1 420 creole_files = [os.path.abspath(config.PATH_ZEPHIR)+os.sep+'modules'+os.sep+str(id_module)+os.sep+'dictionnaire'] 421 # récupération des familles de variables 422 dicos = [] 423 for dic in creole_files: 424 try: 425 # lecture du contenu des dictionnaires 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 # stockage du contenu du dictionnaire 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 # version creole2 438 # chargement de configuration pour un serveur Eole2 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 # définition des dictionnaires à charger 442 dict_dirs = [path_dico] 443 # création de l'objet ZephirDict et lecture des valeurs existantes 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 # dictionnaire variable, libelle 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 # on arrive en fin de dictionnaire 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 # recherche du libellé du module 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 # récupération id et libellé module 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 # vérification owner/mot de passe 494 owner = data[0][3] 495 passmd5 = data[0][4] 496 if owner != cred_user: 497 # vérification du mot de passe 498 if passmd5 != pass_var and passmd5 not in [None,'', BLANK_MD5]: 499 # mauvais mot de passe 500 return 0,u('mot de passe incorrect pour cette variante') 501 # gestion des différentes versions de creole 502 if version == 1: 503 try: 504 # décodage du dictionnaire 505 dico = base64.decodestring(dico_b64) 506 # creole 1 -> encodage en latin-1 507 dico = unicode(dico,'UTF-8').encode('ISO-8859-1') 508 # sauvegarde 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
541 - def xmlrpc_get_mod_dict(self,cred_user,id_module):
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
549 - def _get_mod_dict(self,data):
550 # définition du chemin vers les dictionnaires 551 id_module, version = data[0] 552 try: 553 version = int(version) 554 except: 555 version = 3 556 if version == 1: 557 # non géré sur creole1 558 return 1, [] 559 try: 560 dest_dir=os.path.join(os.path.abspath(config.PATH_MODULES),str(id_module),"dicos") 561 content = [] 562 # cas d'un répertoire 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
570 - def xmlrpc_del_mod_dict(self,cred_user,id_module,dico_name):
571 """renvoie la liste des dictionnaires d'un module. 572 utile pour les modules eole2 (fichier fixé pour les modules eole1) 573 """ 574 # définition du chemin vers les dictionnaires 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 # on supprime le fichier 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 ## gestion des variantes des modules 590 #################################### 591
592 - def _got_variantes(self,variantes,cred_user):
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 # non autorisé : module suivant 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 # recherche des données de l'ancienne variante 611 try: 612 var_src = int(id_var_src) 613 module = int(module) 614 if id_var == "": 615 assert libelle != "" 616 else: 617 # écrasement d'une variante existante 618 id_var = int(id_var) 619 except: 620 return 0, u("""paramètres invalides""") 621 622 # lecture du mot de passe et du module de l'ancienne variante 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 # on veut conserver le propriétaire/mot de passe 632 cred_user = data[0][1] 633 passmd5 = data[0][2] 634 except: 635 # variante créée non trouvée dans la base 636 return 0,u("""module d'origine non retrouvé dans la base""") 637 638 if id_var != "": 639 # copie sur une variante existante 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 # création d'une copie de variante 644 query = """insert into variantes (module,libelle,owner,passmd5) values (%s,%s,%s,%s)""" 645 params = (int(module), libelle, cred_user, passmd5) 646 # id assigné automatiquement dans postgresql 647 # on effectue l'insertion 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 # variante créée non trouvée dans la base 667 return 0,u("""nouvelle variante non retrouvée dans la base""") 668 else: 669 # on recopie l'arborescence de la variante source 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 # modification d'une variante existante 678 if owner != cred_user: 679 # vérification du mot de passe 680 if passmd5 != pass_var and pass_var not in [None,'', BLANK_MD5]: 681 # mauvais mot de passe 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 # stockage de la liaison entre les 2 variantes si copie pour upgrade entre 2 version d'un module 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
716 - def xmlrpc_add_variante(self,cred_user, module, libelle, pass_var=""):
717 """ajoute une variante à un module""" 718 self.parent.s_pool.check_mod_credential(cred_user, module) 719 # on vérifie qu'on a bien récupéré un module 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 # id assigné automatiquement dans postgresql 724 # on effectue l'insertion 725 return self.dbpool.runOperation(query, params).addCallbacks(self._add_variante1, db_client_failed,callbackArgs=[libelle,module]) 726 else: 727 # des attributs manquent 728 return 0, u("""donnez un id de module et un libellé""")
729
730 - def _add_variante1(self,data,libelle,module):
731 """recherche de l'id de la variante créée""" 732 # on récupère l'id de la variante créée 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
737 - def _add_variante2(self,variante):
738 """met en place l'arborescence d'une nouvelle variante""" 739 try: 740 id_variante = variante[0][0] 741 module = variante[0][1] 742 libelle = variante[0][2] 743 except: 744 # variante créée non trouvée dans la base 745 return 0,u("""nouvelle variante non retrouvée dans la base""") 746 else: 747 # on créé l'arborescence de la variante dans les modules 748 os.makedirs(os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+os.sep+'variantes'+os.sep+str(id_variante)) 749 os.makedirs(os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+os.sep+'variantes'+os.sep+str(id_variante)+os.sep+'patchs') 750 os.makedirs(os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+os.sep+'variantes'+os.sep+str(id_variante)+os.sep+'dicos') 751 os.makedirs(os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+os.sep+'variantes'+os.sep+str(id_variante)+os.sep+'fichiers_perso') 752 os.makedirs(os.path.abspath(config.PATH_MODULES)+os.sep+str(module)+os.sep+'variantes'+os.sep+str(id_variante)+os.sep+'fichiers_zephir') 753 # on met à jour les statistiques 754 self.parent.s_pool.stats['serv_variantes'][str(id_variante)] = 0 755 self.parent.dictpool.update_data() 756 return 1,id_variante
757 758
759 - def xmlrpc_del_variante(self,cred_user,id_variante):
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 # on récupère les données de la variante 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
769 - def _del_variante(self,variante):
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 # variante non trouvée dans la base 777 return 0,u("""variante non trouvée dans la base""") 778 else: 779 # on interdit la supression de la variante standard 780 if libelle == 'standard': 781 return 0, u("""la variante standard ne peut pas être supprimée""") 782 # suppression variante dans la base 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
786 - def _del_variante2(self,result,id_module,id_variante):
787 """supression de l'arborescence de la variante""" 788 del(self.parent.s_pool.stats['serv_variantes'][str(id_variante)]) 789 # ok, on supprime son arborescence dans zephir/modules/variantes/id_variante 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 # remonter code -1 si supression de répertoire impossible ? 795 return 0,u("""erreur de supression du répertoire de la variante""") 796 return 1, u('ok')
797
798 - def xmlrpc_fichiers_variante(self,cred_user,id_variante,show_details=False):
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
804 - def _fichiers_zephir(self,data,show_details):
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 # répertoire de stockage de la variante sur zephir 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 # création du dictionnaire de listes des différents fichiers 814 dico_res={} 815 try: 816 # dictionnaires additionnels 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 # fichiers templates variante 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 # patchs variante 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 # RPMS variante 837 # lecture de la liste des rpms supplémentaires 838 fic = open(variante_dir+'/fichiers_zephir/fichiers_variante') 839 data = fic.read().split("\n") 840 fic.close() 841 # recherche de la section des RPMS 842 liste_pkg_var = [] 843 section_rpm = 0 844 for ligne in data: 845 ligne = ligne.strip() 846 if section_rpm == 1: 847 # on regarde si on a bien affaire à un paquetage 848 if not ligne.startswith('#') and ligne != '': 849 # on affiche le nom du paquetage 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 # fichiers du module 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
879 - def xmlrpc_get_variante_perms(self, cred_user, id_variante, filepath=""):
880 """renvoie les informations de permissions associées à un(des) fichier(s) 881 """ 882 # on recherche le répertoire ou la variante est stockée 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
886 - def _get_variante_perms(self, data, filepath):
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 # répertoire de la variante 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
902 - def xmlrpc_del_variante_perms(self, cred_user, id_variante, filepath="", pass_var=""):
903 """supprime les informations de permissions associées à un(des) fichier(s) 904 """ 905 # on recherche le répertoire ou la variante est stockée 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
909 - def _del_variante_perms(self, data, cred_user, filepath, pass_var):
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 # vérification owner/mot de passe 917 if owner != cred_user: 918 # vérification du mot de passe 919 if passmd5 != pass_var and passmd5 not in [None,'',BLANK_MD5]: 920 # mauvais mot de passe 921 return 0,u('mot de passe incorrect pour cette variante') 922 # répertoire de la variante 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
932 - def xmlrpc_set_variante_perms(self, cred_user, id_variante, rights, pass_var=""):
933 """enregistre les informations de permissions associées à un(des) fichier(s) 934 @param rights: dictionnaire au format suviant : {'filepath':[mode,ownership]} 935 """ 936 # on recherche le répertoire ou la variante est stockée 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
940 - def _set_variante_perms(self, data, cred_user, rights, pass_var):
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 # vérification owner/mot de passe 948 if owner != cred_user: 949 # vérification du mot de passe 950 if passmd5 != pass_var and passmd5 not in [None,'',BLANK_MD5]: 951 # mauvais mot de passe 952 return 0,u('mot de passe incorrect pour cette variante') 953 # répertoire de la variante 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
966 - def xmlrpc_get_variante(self,cred_user,id_variante=None):
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
975 - def xmlrpc_edit_variante(self,cred_user,id_variante,dico_modifs,pass_var=""):
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 # vérification du propriétaire/mot de passe 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 # on vérifie que l'identifiant n'est pas modifié 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 # vérification owner/mot de passe 1000 if owner != cred_user: 1001 # vérification du mot de passe 1002 if passmd5 != pass_var and passmd5 not in [None,'',BLANK_MD5]: 1003 # mauvais mot de passe 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 # seul le propriétaire de la variante ou un administrateur a le droit 1009 # de modifier le mot de passe ou le propriétaire 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 # construction de la requête SQL de modification 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
1029 - def xmlrpc_get_migration_infos(self, cred_user, id_module):
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 # récupération des modules 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
1041 - def _get_migration_infos(self, data, id_module):
1042 # recherche des modules vers lesquels on peut migrer 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 # pour les modules nécessitant une migration, pas de choix automatique de la variante 1054 return 1, [] 1055 elif mod_src_version > 1: 1056 mod_src_name = mod_src_lib[:mod_src_lib.rindex('-')] 1057 # migration non standard acceptées 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
1073 - def _get_migration_infos2(self, data, id_module, migration_infos, info_modules):
1074 # correspondances déjà définies 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
1081 - def _get_migration_infos3(self, data, id_module, migration_infos, info_modules):
1082 # liste des destinations possibles pour chaque module 1083 for id_var, id_mod in data: 1084 # on garde seulement les modules de même type 1085 if id_mod in info_modules: 1086 vers_mod = info_modules[id_mod][1] 1087 # si migration autorisée 1088 if vers_mod in migration_infos: 1089 # liste des variantes dispos 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
1096 - def xmlrpc_variantes_upgrade(self, cred_user, var_src, var_migr):
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 # supression des anciennes correspondances 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
1113 - def _variantes_upgrade2(self, result, var_src, var_dest):
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 # si la variante ne nous appartient pas, on interdit la modification si mauvais mot de passe 1147 if owner != cred_user: 1148 # vérification du mot de passe 1149 if passwd != pass_var and pass_var not in [None,'',BLANK_MD5]: 1150 # mauvais mot de passe 1151 return 0,u('mot de passe incorrect pour cette variante') 1152 # on met en place les différents types de fichiers 1153 dest_dir=os.path.abspath(config.PATH_MODULES)+os.sep+str(id_module)+os.sep+"variantes"+os.sep+str(id_variante) 1154 # dans le cas d'un serveur eole1, on encode le contenu des fichiers en iso8859 si nécessaire 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 # on récupère la liste des fichiers à supprimer existante 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 # on regarde si le fichier était dans la liste des fichiers obsolètes 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 # on vérifie si des paquets non autorisés sont listés 1181 if dico_files.has_key('rpms_var'): 1182 use_pool = self.parent.dictpool.check_module(id_module) 1183 if use_pool: 1184 # liste des paquets gérés au niveau variante/module 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 # si un paquet demandé est dans la liste, on l'interdit 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 # dictionnaires locaux 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 # on reprend la liste des fichiers existants 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 # on ajoute le fichier à la liste si il n'est pas déjà présent 1235 localpath = "" 1236 if len(fichier) == 3: 1237 localpath = fichier[2] 1238 # on enlève le nom de conteneur si présent 1239 conteneur = "" 1240 if '::' in fichier[0]: 1241 fic_path, conteneur = fichier[0].split('::') 1242 else: 1243 fic_path = fichier[0] 1244 # nettoyage du nom de fichier 1245 nom_fic = fic_path.replace("\\","/") 1246 # on supprime les séparateurs en fin de ligne 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 # on ajoute le fichier à la liste si il n'est pas déjà présent et si il n'est pas dans un sous répertoire 1257 if nom_final not in fichiers.split('\n') and localpath == "": 1258 fichiers = fichiers.strip() + '\n' + nom_final +'\n' 1259 # on écrit le contenu du fichier 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 # rpms 1272 if dico_files.has_key('rpms_var'): 1273 for rpm in dico_files['rpms_var']: 1274 # on ajoute le rpm si il n'est pas présent 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 # synchronisation des fichiers de dictionnaires 1283 # si gérés pour ce module 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 # si la variante ne nous appartient pas, on interdit la modification si mauvais mot de passe 1302 if owner != cred_user: 1303 # vérification du mot de passe 1304 if passwd != pass_var and pass_var not in [None,'',BLANK_MD5]: 1305 # mauvais mot de passe 1306 return 0,u('mot de passe incorrect pour cette variante') 1307 # on met en place les différents types de fichiers 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 # on récupère la liste des fichiers à supprimer existante 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 # dictionnaires locaux 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 # on supprime les droits associés si nécessaire 1331 self.parent.s_pool.del_file_perms(dest_dir,'fichiers_perso'+os.sep+template) 1332 # si demandé, on ajoute le template à la liste des fichiers à supprimer 1333 # sur le serveur cible 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 # on reprend la liste des fichiers existants 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 # on supprime le fichier de la liste 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 # on efface le fichier 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 # on supprime les droits associés si nécessaire 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 # si demandé, on ajoute le fichier à la liste des fichiers à supprimer 1387 # sur le serveur cible 1388 if remove: 1389 fic_rem = fichier.replace("\\","/") 1390 if fic_rem not in liste_remove: 1391 liste_remove.append(fic_rem) 1392 1393 # rpms 1394 for rpm in dico_files['rpms_var']: 1395 # on supprime le rpm si il existe 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 # liste des fichiers à supprimer 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
1417 - def xmlrpc_get_var_file(self,cred_user,id_var,id_module,path,show_details=False):
1418 """renvoie le contenu d'un fichier de variante""" 1419 # définition du chemin de la variante 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
1424 - def _get_var_file(self,data,path,show_details):
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 # on lit le fichier 1437 try: 1438 # cas d'un répertoire 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 # on encode le contenu en base64 1456 if mod_version == 1: 1457 try: 1458 content = unicode(content,'ISO-8859-1').encode(config.charset) 1459 except: 1460 # le fichier n'est pas en unicode ?? 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
1469 - def xmlrpc_export_variante(self,cred_user,id_variante):
1470 """envoie le contenu d'une variante sur un autre zephir""" 1471 # on recherche le répertoire ou la variante est stockée 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
1475 - def _export_variante(self,data):
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 # répertoire de la variante 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 # on crée une archive de ce répertoire 1484 archive=str(time.time()) 1485 if os.path.isdir(var_dir): 1486 # création du fichier tar à envoyer 1487 cmd_tar = ['cd ',var_dir,';','tar','-chzf','/tmp/'+archive+'.tgz','*'] 1488 cmd_tar.append('2>&1 >/dev/null') 1489 # exécution de tar 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 # calcul et stockage d'un checksum md5 de l'archive 1495 cmd_checksum = """cd /tmp/; md5sum -b %s.tgz > %s.md5""" % (archive,archive) 1496 res=os.system(cmd_checksum) 1497 # on stocke en mémoire les données 1498 try: 1499 # le checksum 1500 f = open('/tmp'+os.sep+archive+'.md5') 1501 data1 = f.read() 1502 f.close() 1503 os.unlink('/tmp'+os.sep+archive+'.md5') 1504 # l'archive 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 # création d'un proxy vers le serveur zephir distant 1520 z=EoleProxy("https://%s:%s@%s:%s" % (login_distant,pwd_distant,zephir_distant,config.PORT_ZEPHIR)) 1521 # on vérifie l'existence des variantes des 2 cotés 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 # on recherche le module de la variante locale 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
1533 - def _import_variante(self,data,proxy,id_distant,cred_user,pwd_var):
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 # on vérifie le mot de passe de la variante 1543 if owner != cred_user and pwd_var != passmd5: 1544 return 0,u("""mauvais mot de passe de variante""") 1545 else: 1546 # définition du chemin de destination 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 # on regarde si des fichiers existent déjà 1550 if not os.path.exists(var_dir): 1551 return 0,u("""répertoire de la variante de destination non trouvé""") 1552 # onrécupère les données de la variante source 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 # nom de l'archive 1558 archive=res[1][0] 1559 # somme md5 1560 var_data=base64.decodestring(res[1][1]) 1561 # contenu de l'archive 1562 md5_data=base64.decodestring(res[1][2]) 1563 try: 1564 # on supprime l'ancien répertoire de la variante 1565 shutil.rmtree(var_dir) 1566 # on recrée un répertoire vide 1567 os.makedirs(var_dir) 1568 # on recrée l'archive et le fichier md5 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 # on vérifie la somme md5 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 # on décompresse l'archive 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 # on supprime les fichiers temporaires 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 # l'import s'est terminé correctement 1591 return 1,u("ok")
1592