1
2 '''
3 # DESCRIPTION:
4 # Entropy Object Oriented Interface
5
6 Copyright (C) 2007-2009 Fabio Erculiani
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 '''
22
23 from __future__ import with_statement
24 import os
25 import time
26 import shutil
27 import subprocess
28 import random
29 from entropy.i18n import _
30 from entropy.db import dbapi2, LocalRepository
31 from entropy.misc import TimeScheduled
32 from entropy.const import *
33 from entropy.exceptions import *
34 from entropy.output import *
35
37
38 import entropy.dump as dumpTools
39 import entropy.tools as entropyTools
40 import socket
41 - def __init__(self, EquoInstance, reponames = [], forceUpdate = False, noEquoCheck = False, fetchSecurity = True):
42
43 self.LockScanner = None
44 from entropy.client.interfaces import Client
45 if not isinstance(EquoInstance,Client):
46 mytxt = _("A valid Equo instance or subclass is needed")
47 raise IncorrectParameter("IncorrectParameter: %s" % (mytxt,))
48
49 self.supported_download_items = (
50 "db","rev","ck",
51 "lock","mask", "system_mask", "dbdump", "conflicting_tagged",
52 "dbdumplight", "dbdumplightck", "dbdumpck", "lic_whitelist",
53 "make.conf", "package.mask", "package.unmask", "package.keywords",
54 "profile.link", "package.use", "server.cert", "ca.cert",
55 "meta_file", "notice_board"
56 )
57 self.big_socket_timeout = 25
58 self.Entropy = EquoInstance
59 from entropy.cache import EntropyCacher
60 self.Cacher = EntropyCacher()
61 self.dbapi2 = dbapi2
62 self.reponames = reponames
63 self.forceUpdate = forceUpdate
64 self.syncErrors = False
65 self.dbupdated = False
66 self.newEquo = False
67 self.fetchSecurity = fetchSecurity
68 self.noEquoCheck = noEquoCheck
69 self.alreadyUpdated = 0
70 self.notAvailable = 0
71 self.valid_eapis = [1,2,3]
72 self.reset_dbformat_eapi(None)
73 self.current_repository_got_locked = False
74 self.updated_repos = set()
75
76
77 if not self.Entropy.SystemSettings['repositories']['available']:
78 mytxt = _("No repositories specified in %s") % (etpConst['repositoriesconf'],)
79 raise MissingParameter("MissingParameter: %s" % (mytxt,))
80
81 if not self.reponames:
82 self.reponames.extend(self.Entropy.SystemSettings['repositories']['available'].keys()[:])
83
85 if self.LockScanner != None:
86 self.LockScanner.kill()
87
107
116
140
141
143 if repoid not in self.reponames:
144 mytxt = _("Repository is not listed in self.reponames")
145 raise InvalidData("InvalidData: %s" % (mytxt,))
146
148
149 self.__validate_repository_id(repo)
150
151 repo_settings = self.Entropy.SystemSettings['repositories']
152 dbc_format = repo_settings['available'][repo]['dbcformat']
153 cmethod = etpConst['etpdatabasecompressclasses'].get(dbc_format)
154 if cmethod == None:
155 mytxt = _("Wrong database compression method")
156 raise InvalidDataType("InvalidDataType: %s" % (mytxt,))
157
158 return cmethod
159
161
162 self.__validate_repository_id(repo)
163
164
165 if not os.path.isdir(self.Entropy.SystemSettings['repositories']['available'][repo]['dbpath']):
166 os.makedirs(self.Entropy.SystemSettings['repositories']['available'][repo]['dbpath'],0775)
167
168 const_setup_perms(etpConst['etpdatabaseclientdir'],etpConst['entropygid'])
169
171
172 if item not in self.supported_download_items:
173 mytxt = _("Supported items: %s") % (self.supported_download_items,)
174 raise InvalidData("InvalidData: %s" % (mytxt,))
175 if (item in ("db","dbdump", "dbdumpck",)) and (cmethod == None):
176 mytxt = _("For %s, cmethod can't be None") % (item,)
177 raise InvalidData("InvalidData: %s" % (mytxt,))
178
179 repo_db = self.Entropy.SystemSettings['repositories']['available'][repo]['database']
180 repo_dbpath = self.Entropy.SystemSettings['repositories']['available'][repo]['dbpath']
181 ec_rev = etpConst['etpdatabaserevisionfile']
182 ec_hash = etpConst['etpdatabasehashfile']
183 ec_maskfile = etpConst['etpdatabasemaskfile']
184 ec_sysmaskfile = etpConst['etpdatabasesytemmaskfile']
185 ec_confl_taged = etpConst['etpdatabaseconflictingtaggedfile']
186 make_conf_file = os.path.basename(etpConst['spm']['global_make_conf'])
187 pkg_mask_file = os.path.basename(etpConst['spm']['global_package_mask'])
188 pkg_unmask_file = os.path.basename(etpConst['spm']['global_package_unmask'])
189 pkg_keywords_file = os.path.basename(etpConst['spm']['global_package_keywords'])
190 pkg_use_file = os.path.basename(etpConst['spm']['global_package_use'])
191 sys_profile_lnk = etpConst['spm']['global_make_profile_link_name']
192 pkg_lic_wl_file = etpConst['etpdatabaselicwhitelistfile']
193 repo_lock_file = etpConst['etpdatabasedownloadlockfile']
194 ca_cert_file = etpConst['etpdatabasecacertfile']
195 server_cert_file = etpConst['etpdatabaseservercertfile']
196 notice_board_filename = os.path.basename(self.Entropy.SystemSettings['repositories']['available'][repo]['notice_board'])
197 meta_file = etpConst['etpdatabasemetafilesfile']
198 ec_cm2 = None
199 ec_cm3 = None
200 ec_cm4 = None
201 ec_cm5 = None
202 ec_cm6 = None
203 if cmethod != None:
204 ec_cm2 = etpConst[cmethod[2]]
205 ec_cm3 = etpConst[cmethod[3]]
206 ec_cm4 = etpConst[cmethod[4]]
207 ec_cm5 = etpConst[cmethod[5]]
208 ec_cm6 = etpConst[cmethod[6]]
209
210 mymap = {
211 'db': ("%s/%s" % (repo_db,ec_cm2,),"%s/%s" % (repo_dbpath,ec_cm2,),),
212 'dbdump': ("%s/%s" % (repo_db,ec_cm3,),"%s/%s" % (repo_dbpath,ec_cm3,),),
213 'dbdumplight': ("%s/%s" % (repo_db,ec_cm5,),"%s/%s" % (repo_dbpath,ec_cm5,),),
214 'rev': ("%s/%s" % (repo_db,ec_rev,),"%s/%s" % (repo_dbpath,ec_rev,),),
215 'ck': ("%s/%s" % (repo_db,ec_hash,),"%s/%s" % (repo_dbpath,ec_hash,),),
216 'dbdumpck': ("%s/%s" % (repo_db,ec_cm4,),"%s/%s" % (repo_dbpath,ec_cm4,),),
217 'dbdumplightck': ("%s/%s" % (repo_db,ec_cm6,),"%s/%s" % (repo_dbpath,ec_cm6,),),
218 'mask': ("%s/%s" % (repo_db,ec_maskfile,),"%s/%s" % (repo_dbpath,ec_maskfile,),),
219 'system_mask': ("%s/%s" % (repo_db,ec_sysmaskfile,),"%s/%s" % (repo_dbpath,ec_sysmaskfile,),),
220 'conflicting_tagged': ("%s/%s" % (repo_db,ec_confl_taged,),"%s/%s" % (repo_dbpath,ec_confl_taged,),),
221 'make.conf': ("%s/%s" % (repo_db,make_conf_file,),"%s/%s" % (repo_dbpath,make_conf_file,),),
222 'package.mask': ("%s/%s" % (repo_db,pkg_mask_file,),"%s/%s" % (repo_dbpath,pkg_mask_file,),),
223 'package.unmask': ("%s/%s" % (repo_db,pkg_unmask_file,),"%s/%s" % (repo_dbpath,pkg_unmask_file,),),
224 'package.keywords': ("%s/%s" % (repo_db,pkg_keywords_file,),"%s/%s" % (repo_dbpath,pkg_keywords_file,),),
225 'package.use': ("%s/%s" % (repo_db,pkg_use_file,),"%s/%s" % (repo_dbpath,pkg_use_file,),),
226 'profile.link': ("%s/%s" % (repo_db,sys_profile_lnk,),"%s/%s" % (repo_dbpath,sys_profile_lnk,),),
227 'lic_whitelist': ("%s/%s" % (repo_db,pkg_lic_wl_file,),"%s/%s" % (repo_dbpath,pkg_lic_wl_file,),),
228 'lock': ("%s/%s" % (repo_db,repo_lock_file,),"%s/%s" % (repo_dbpath,repo_lock_file,),),
229 'server.cert': ("%s/%s" % (repo_db,server_cert_file,),"%s/%s" % (repo_dbpath,server_cert_file,),),
230 'ca.cert': ("%s/%s" % (repo_db,ca_cert_file,),"%s/%s" % (repo_dbpath,ca_cert_file,),),
231 'notice_board': (self.Entropy.SystemSettings['repositories']['available'][repo]['notice_board'],"%s/%s" % (repo_dbpath,notice_board_filename,),),
232 'meta_file': ("%s/%s" % (repo_db,meta_file,),"%s/%s" % (repo_dbpath,meta_file,),),
233 }
234
235 return mymap.get(item)
236
238
239 dbfilenameid = cmethod[2]
240 self.__validate_repository_id(repo)
241 repo_dbpath = self.Entropy.SystemSettings['repositories']['available'][repo]['dbpath']
242
243 def remove_eapi1(repo_dbpath, dbfilenameid):
244 if os.path.isfile(repo_dbpath+"/"+etpConst['etpdatabasehashfile']):
245 os.remove(repo_dbpath+"/"+etpConst['etpdatabasehashfile'])
246 if os.path.isfile(repo_dbpath+"/"+etpConst[dbfilenameid]):
247 os.remove(repo_dbpath+"/"+etpConst[dbfilenameid])
248 if os.path.isfile(repo_dbpath+"/"+etpConst['etpdatabaserevisionfile']):
249 os.remove(repo_dbpath+"/"+etpConst['etpdatabaserevisionfile'])
250
251 if self.dbformat_eapi == 1:
252 remove_eapi1(repo_dbpath, dbfilenameid)
253 elif self.dbformat_eapi in (2,3,):
254 remove_eapi1(repo_dbpath, dbfilenameid)
255 if os.path.isfile(repo_dbpath+"/"+cmethod[6]):
256 os.remove(repo_dbpath+"/"+cmethod[6])
257 if os.path.isfile(repo_dbpath+"/"+etpConst[cmethod[5]]):
258 os.remove(repo_dbpath+"/"+etpConst[cmethod[5]])
259 if os.path.isfile(repo_dbpath+"/"+etpConst['etpdatabaserevisionfile']):
260 os.remove(repo_dbpath+"/"+etpConst['etpdatabaserevisionfile'])
261 else:
262 mytxt = _("self.dbformat_eapi must be in (1,2,3,)")
263 raise InvalidData('InvalidData: %s' % (mytxt,))
264
266
267 self.__validate_repository_id(repo)
268 rc = 0
269 path = None
270
271 if self.dbformat_eapi == 1:
272 myfile = self.Entropy.SystemSettings['repositories']['available'][repo]['dbpath']+"/"+etpConst[cmethod[2]]
273 try:
274 myfunc = getattr(self.entropyTools, cmethod[1])
275 path = myfunc(myfile)
276 except EOFError:
277 rc = 1
278 if os.path.isfile(myfile):
279 os.remove(myfile)
280 elif self.dbformat_eapi == 2:
281 myfile = self.Entropy.SystemSettings['repositories']['available'][repo]['dbpath']+"/"+etpConst[cmethod[5]]
282 try:
283 mycall = getattr(self.entropyTools,cmethod[1])
284 path = mycall(myfile)
285 except EOFError:
286 rc = 1
287 if os.path.isfile(myfile):
288 os.remove(myfile)
289 else:
290 mytxt = _("self.dbformat_eapi must be in (1,2)")
291 raise InvalidData('InvalidData: %s' % (mytxt,))
292
293 if rc == 0:
294 self.Entropy.setup_default_file_perms(path)
295
296 return rc
297
299
300 self.__validate_repository_id(repo)
301
302 if self.dbformat_eapi == 1:
303 dbfile = etpConst['etpdatabasefile']
304 try:
305 f = open(self.Entropy.SystemSettings['repositories']['available'][repo]['dbpath']+"/"+etpConst['etpdatabasehashfile'],"r")
306 md5hash = f.readline().strip()
307 md5hash = md5hash.split()[0]
308 f.close()
309 except:
310 return -1
311 elif self.dbformat_eapi == 2:
312 dbfile = etpConst[cmethod[5]]
313 try:
314 f = open(self.Entropy.SystemSettings['repositories']['available'][repo]['dbpath']+"/"+etpConst[cmethod[6]],"r")
315 md5hash = f.readline().strip()
316 md5hash = md5hash.split()[0]
317 f.close()
318 except:
319 return -1
320 else:
321 mytxt = _("self.dbformat_eapi must be in (1,2)")
322 raise InvalidData('InvalidData: %s' % (mytxt,))
323
324 rc = self.entropyTools.compare_md5(self.Entropy.SystemSettings['repositories']['available'][repo]['dbpath']+"/"+dbfile,md5hash)
325 return rc
326
327
328
330
331 self.__validate_repository_id(repo)
332
333 url = self.Entropy.SystemSettings['repositories']['available'][repo]['database']+"/"+etpConst['etpdatabaserevisionfile']
334 status = self.entropyTools.get_remote_data(url)
335 if (status):
336 status = status[0].strip()
337 try:
338 status = int(status)
339 except ValueError:
340 status = -1
341 return status
342 else:
343 return -1
344
346 self.__validate_repository_id(repo)
347 url = self.Entropy.SystemSettings['repositories']['available'][repo]['database']+"/"+etpConst['etpdatabaseeapi3lockfile']
348 data = self.entropyTools.get_remote_data(url)
349 if not data:
350 return False
351 return True
352
356
358
359 self.__validate_repository_id(repo)
360
361 onlinestatus = self.get_online_repository_revision(repo)
362 if (onlinestatus != -1):
363 localstatus = self.Entropy.get_repository_revision(repo)
364 if (localstatus == onlinestatus) and (not self.forceUpdate):
365 return False
366 return True
367
369
370 self.__validate_repository_id(repo)
371
372 rc = self.download_item("lock", repo, disallow_redirect = True)
373 if rc:
374 self.syncErrors = True
375 return False
376 return True
377
382
383
384 - def download_item(self, item, repo, cmethod = None, lock_status_func = None, disallow_redirect = True):
385
386 self.__validate_repository_id(repo)
387 url, filepath = self._construct_paths(item, repo, cmethod)
388
389
390
391
392 if os.path.isfile(filepath):
393 os.remove(filepath)
394 filepath_dir = os.path.dirname(filepath)
395 if not os.path.isdir(filepath_dir) and not os.path.lexists(filepath_dir):
396 os.makedirs(filepath_dir,0775)
397 const_setup_perms(filepath_dir, etpConst['entropygid'])
398
399 fetchConn = self.Entropy.urlFetcher(
400 url,
401 filepath,
402 resume = False,
403 abort_check_func = lock_status_func,
404 disallow_redirect = disallow_redirect
405 )
406 fetchConn.progress = self.Entropy.progress
407
408 rc = fetchConn.download()
409 del fetchConn
410 if rc in ("-1","-2","-3","-4"):
411 return False
412 self.Entropy.setup_default_file_perms(filepath)
413 return True
414
416 dbfilename = etpConst['etpdatabasefile']
417 if self.dbformat_eapi == 2:
418 dbfilename = etpConst[cmethod[5]]
419
420 mytxt = "%s %s %s" % (
421 red(_("Checking downloaded database")),
422 darkgreen(dbfilename),
423 red("..."),
424 )
425 self.Entropy.updateProgress(
426 mytxt,
427 importance = 0,
428 back = True,
429 type = "info",
430 header = "\t"
431 )
432 db_status = self.__verify_database_checksum(repo, cmethod)
433 if db_status == -1:
434 mytxt = "%s. %s !" % (red(_("Cannot open digest")),red(_("Cannot verify database integrity")),)
435 self.Entropy.updateProgress(
436 mytxt,
437 importance = 1,
438 type = "warning",
439 header = "\t"
440 )
441 elif db_status:
442 mytxt = "%s: %s" % (red(_("Downloaded database status")),bold(_("OK")),)
443 self.Entropy.updateProgress(
444 mytxt,
445 importance = 1,
446 type = "info",
447 header = "\t"
448 )
449 else:
450 mytxt = "%s: %s" % (red(_("Downloaded database status")),darkred(_("ERROR")),)
451 self.Entropy.updateProgress(
452 mytxt,
453 importance = 1,
454 type = "error",
455 header = "\t"
456 )
457 mytxt = "%s. %s" % (red(_("An error occured while checking database integrity")),red(_("Giving up")),)
458 self.Entropy.updateProgress(
459 mytxt,
460 importance = 1,
461 type = "error",
462 header = "\t"
463 )
464 return 1
465 return 0
466
467
498
500
501 dbfile = os.path.join(self.Entropy.SystemSettings['repositories']['available'][repo]['dbpath'],etpConst['etpdatabasefile'])
502 mydbconn = None
503 try:
504 mydbconn = self.Entropy.open_generic_database(dbfile, xcache = False, indexing_override = False)
505 mydbconn.validateDatabase()
506 except (
507 self.Entropy.dbapi2.OperationalError,
508 self.Entropy.dbapi2.IntegrityError,
509 SystemDatabaseError,
510 IOError,
511 OSError,):
512 mydbconn = None
513 return mydbconn
514
516
517 product = self.Entropy.SystemSettings['repositories']['product']
518 data = eapi3_interface.CmdInterface.differential_packages_comparison(
519 session, idpackages, repo, etpConst['currentarch'], product
520 )
521 if isinstance(data,bool):
522 return False,False,False
523 elif not isinstance(data,dict):
524 return None,None,None
525 elif not data.has_key('added') or \
526 not data.has_key('removed') or \
527 not data.has_key('checksum'):
528 return None,None,None
529 return data['added'],data['removed'],data['checksum']
530
539
541
542 def prepare_exit(mysock, session = None):
543 try:
544 if session != None:
545 mysock.close_session(session)
546 mysock.disconnect()
547 except (self.socket.error,):
548 pass
549
550 eapi3_interface = self.get_eapi3_connection(repo)
551 if eapi3_interface == None: return False
552
553 session = eapi3_interface.open_session()
554
555
556 try:
557 mydbconn = self.get_eapi3_local_database(repo)
558 myidpackages = mydbconn.listAllIdpackages()
559 except (self.dbapi2.DatabaseError,self.dbapi2.IntegrityError,self.dbapi2.OperationalError,AttributeError,):
560 prepare_exit(eapi3_interface, session)
561 return False
562
563 added_ids, removed_ids, checksum = self.get_eapi3_database_differences(
564 eapi3_interface, repo,
565 myidpackages, session
566 )
567 if (None in (added_ids,removed_ids,checksum)) or \
568 (not added_ids and not removed_ids and self.forceUpdate):
569 mydbconn.closeDB()
570 prepare_exit(eapi3_interface, session)
571 return False
572
573 elif not checksum:
574 mydbconn.closeDB()
575 prepare_exit(eapi3_interface, session)
576 mytxt = "%s: %s" % ( blue(_("EAPI3 Service status")), darkred(_("remote database suddenly locked")),)
577 self.Entropy.updateProgress(
578 mytxt,
579 importance = 0,
580 type = "info",
581 header = blue(" # "),
582 )
583 return None
584
585
586 if len(added_ids) > threshold:
587 mytxt = "%s: %s (%s: %s/%s)" % (
588 blue(_("EAPI3 Service")), darkred(_("skipping differential sync")),
589 brown(_("threshold")), blue(str(len(added_ids))), darkred(str(threshold)),
590 )
591 self.Entropy.updateProgress(
592 mytxt,
593 importance = 0,
594 type = "info",
595 header = blue(" # "),
596 )
597 mydbconn.closeDB()
598 prepare_exit(eapi3_interface, session)
599 return False
600
601 count = 0
602 added_segments = []
603 mytmp = set()
604
605 for idpackage in added_ids:
606 count += 1
607 mytmp.add(idpackage)
608 if count % chunk_size == 0:
609 added_segments.append(list(mytmp))
610 mytmp.clear()
611 if mytmp: added_segments.append(list(mytmp))
612 del mytmp
613
614
615 count = 0
616 maxcount = len(added_segments)
617 product = self.Entropy.SystemSettings['repositories']['product']
618 for segment in added_segments:
619
620 count += 1
621 mytxt = "%s %s" % (blue(_("Fetching segments")), "...",)
622 self.Entropy.updateProgress(
623 mytxt, importance = 0, type = "info",
624 header = "\t", back = True, count = (count,maxcount,)
625 )
626 fetch_count = 0
627 max_fetch_count = 5
628
629 while 1:
630
631
632 if fetch_count > max_fetch_count:
633 mydbconn.closeDB()
634 prepare_exit(eapi3_interface, session)
635 return False
636
637 fetch_count += 1
638 pkgdata = eapi3_interface.CmdInterface.get_strict_package_information(
639 session, segment, repo, etpConst['currentarch'], product
640 )
641 if pkgdata == None:
642 mytxt = "%s: %s" % ( blue(_("Fetch error on segment")),
643 darkred(str(segment)),)
644 self.Entropy.updateProgress(
645 mytxt, importance = 1, type = "warning",
646 header = "\t", count = (count,maxcount,)
647 )
648 continue
649 elif not pkgdata:
650 mytxt = "%s: %s" % (
651 blue(_("Service status")),
652 darkred("remote database suddenly locked"),
653 )
654 self.Entropy.updateProgress(
655 mytxt, importance = 1, type = "info",
656 header = "\t", count = (count,maxcount,)
657 )
658 mydbconn.closeDB()
659 prepare_exit(eapi3_interface, session)
660 return None
661 elif isinstance(pkgdata,tuple):
662 mytxt = "%s: %s, %s. %s" % (
663 blue(_("Service status")),
664 pkgdata[0], pkgdata[1],
665 darkred("Error processing the command"),
666 )
667 self.Entropy.updateProgress(
668 mytxt, importance = 1, type = "info",
669 header = "\t", count = (count,maxcount,)
670 )
671 mydbconn.closeDB()
672 prepare_exit(eapi3_interface, session)
673 return None
674
675 try:
676 for idpackage in pkgdata:
677 self.dumpTools.dumpobj(
678 "%s%s" % (etpCache['eapi3_fetch'],idpackage,),
679 pkgdata[idpackage],
680 ignore_exceptions = False
681 )
682 except (IOError,EOFError,OSError,), e:
683 mytxt = "%s: %s: %s." % (
684 blue(_("Local status")),
685 darkred("Error storing data"),
686 e,
687 )
688 self.Entropy.updateProgress(
689 mytxt, importance = 1, type = "info",
690 header = "\t", count = (count,maxcount,)
691 )
692 mydbconn.closeDB()
693 prepare_exit(eapi3_interface, session)
694 return None
695
696 break
697
698 del added_segments
699
700 repo_metadata = self.get_eapi3_repository_metadata(eapi3_interface,
701 repo, session)
702 metadata_elements = ("sets", "treeupdates_actions",
703 "treeupdates_digest", "library_idpackages",)
704 for elem in metadata_elements:
705 if elem not in repo_metadata:
706 mydbconn.closeDB()
707 prepare_exit(eapi3_interface, session)
708 mytxt = "%s: %s" % (
709 blue(_("EAPI3 Service status")),
710 darkred(_("cannot fetch repository metadata")),
711 )
712 self.Entropy.updateProgress(
713 mytxt,
714 importance = 0,
715 type = "info",
716 header = blue(" # "),
717 )
718 return None
719
720
721 try:
722 mydbconn.setRepositoryUpdatesDigest(repo,
723 repo_metadata['treeupdates_digest'])
724 mydbconn.bumpTreeUpdatesActions(
725 repo_metadata['treeupdates_actions'])
726 except (self.dbapi2.Error,):
727 mydbconn.closeDB()
728 prepare_exit(eapi3_interface, session)
729 mytxt = "%s: %s" % (
730 blue(_("EAPI3 Service status")),
731 darkred(_("cannot update treeupdates data")),
732 )
733 self.Entropy.updateProgress(
734 mytxt,
735 importance = 0,
736 type = "info",
737 header = blue(" # "),
738 )
739 return None
740
741
742 try:
743 mydbconn.clearPackageSets()
744 mydbconn.insertPackageSets(repo_metadata['sets'])
745 except (self.dbapi2.Error,):
746 mydbconn.closeDB()
747 prepare_exit(eapi3_interface, session)
748 mytxt = "%s: %s" % (
749 blue(_("EAPI3 Service status")),
750 darkred(_("cannot update package sets data")),
751 )
752 self.Entropy.updateProgress(
753 mytxt,
754 importance = 0,
755 type = "info",
756 header = blue(" # "),
757 )
758 return None
759
760
761 try:
762 mydbconn.clearNeededLibraryIdpackages()
763 mydbconn.setNeededLibraryIdpackages(
764 repo_metadata['library_idpackages'])
765 except (self.dbapi2.Error,):
766 mydbconn.closeDB()
767 prepare_exit(eapi3_interface, session)
768 mytxt = "%s: %s" % (
769 blue(_("EAPI3 Service status")),
770 darkred(_("cannot update library data")),
771 )
772 self.Entropy.updateProgress(
773 mytxt,
774 importance = 0,
775 type = "info",
776 header = blue(" # "),
777 )
778 return None
779
780
781
782 prepare_exit(eapi3_interface, session)
783
784
785 count = 0
786 maxcount = len(added_ids)
787 for idpackage in added_ids:
788 count += 1
789 mydata = self.Cacher.pop("%s%s" % (etpCache['eapi3_fetch'],idpackage,))
790 if mydata == None:
791 mytxt = "%s: %s" % (
792 blue(_("Fetch error on segment while adding")),
793 darkred(str(segment)),
794 )
795 self.Entropy.updateProgress(
796 mytxt, importance = 1, type = "warning",
797 header = "\t", count = (count,maxcount,)
798 )
799 mydbconn.closeDB()
800 return False
801
802 mytxt = "%s %s" % (blue(_("Injecting package")), darkgreen(mydata['atom']),)
803 self.Entropy.updateProgress(
804 mytxt, importance = 0, type = "info",
805 header = "\t", back = True, count = (count,maxcount,)
806 )
807 mydbconn.addPackage(
808 mydata, revision = mydata['revision'],
809 idpackage = idpackage, do_remove = False,
810 do_commit = False, formatted_content = True
811 )
812
813 self.Entropy.updateProgress(
814 blue(_("Packages injection complete")), importance = 0,
815 type = "info", header = "\t",
816 )
817
818
819 maxcount = len(removed_ids)
820 count = 0
821 for idpackage in removed_ids:
822 myatom = mydbconn.retrieveAtom(idpackage)
823 count += 1
824 mytxt = "%s: %s" % (blue(_("Removing package")), darkred(str(myatom)),)
825 self.Entropy.updateProgress(
826 mytxt, importance = 0, type = "info",
827 header = "\t", back = True, count = (count,maxcount,)
828 )
829 mydbconn.removePackage(idpackage, do_cleanup = False, do_commit = False)
830
831 self.Entropy.updateProgress(
832 blue(_("Packages removal complete")),
833 importance = 0, type = "info",
834 header = "\t",
835 )
836
837 mydbconn.commitChanges()
838 mydbconn.clearCache()
839
840 result = False
841 mychecksum = mydbconn.database_checksum(do_order = True, strict = False, strings = True)
842 if checksum == mychecksum:
843 result = True
844 else:
845 mytxt = "%s: %s: %s | %s: %s" % (
846 blue(_("Database checksum doesn't match remote.")),
847 darkgreen(_("local")), mychecksum,
848 darkred(_("remote")), checksum,
849 )
850 self.Entropy.updateProgress(
851 mytxt, importance = 0,
852 type = "info", header = "\t",
853 )
854
855 mydbconn.closeDB()
856 return result
857
859
860 self.dbupdated = False
861 repocount = 0
862 repolength = len(self.reponames)
863 for repo in self.reponames:
864
865 repocount += 1
866 self.reset_dbformat_eapi(repo)
867 self.show_repository_information(repo, (repocount,repolength))
868
869 if not self.forceUpdate:
870 updated = self.handle_repository_update(repo)
871 if updated:
872 self.Entropy.cycleDone()
873 self.alreadyUpdated += 1
874 continue
875
876 locked = self.handle_repository_lock(repo)
877 if locked:
878 self.notAvailable += 1
879 self.Entropy.cycleDone()
880 continue
881
882
883 self.clear_repository_cache(repo)
884 self.__ensure_repository_path(repo)
885
886
887
888 do_skip = False
889 skip_this_repo = False
890 db_down_status = False
891 do_db_update_transfer = False
892 rc = 0
893
894 dumpfile = os.path.join(
895 self.Entropy.SystemSettings['repositories']['available'][repo]['dbpath'],
896 etpConst['etpdatabasedumplight'])
897 dbfile = os.path.join(self.Entropy.SystemSettings['repositories']['available'][repo]['dbpath'],etpConst['etpdatabasefile'])
898 dbfile_old = dbfile+".sync"
899 cmethod = self.__validate_compression_method(repo)
900
901 while 1:
902
903 if do_skip:
904 break
905
906 if self.dbformat_eapi < 3:
907
908 down_status = self.handle_database_download(repo, cmethod)
909 if not down_status:
910 self.Entropy.cycleDone()
911 self.notAvailable += 1
912 do_skip = True
913 skip_this_repo = True
914 continue
915 db_down_status = self.handle_database_checksum_download(repo, cmethod)
916 break
917
918 elif self.dbformat_eapi == 3 and not (os.path.isfile(dbfile) and os.access(dbfile,os.W_OK)):
919
920 do_db_update_transfer = None
921 self.dbformat_eapi -= 1
922 continue
923
924 elif self.dbformat_eapi == 3:
925
926 status = False
927 try:
928 status = self.handle_eapi3_database_sync(repo)
929 except self.socket.error, e:
930 mytxt = "%s: %s" % (
931 blue(_("EAPI3 Service error")),
932 darkred(unicode(e)),
933 )
934 self.Entropy.updateProgress(
935 mytxt,
936 importance = 0,
937 type = "info",
938 header = blue(" # "),
939 )
940 except:
941
942 self.__remove_repository_files(repo, cmethod)
943 raise
944
945 if status == None:
946 time.sleep(5)
947 locked = self.handle_repository_lock(repo)
948 if locked:
949 self.Entropy.cycleDone()
950 self.notAvailable += 1
951 do_skip = True
952 skip_this_repo = True
953 else:
954 do_db_update_transfer = None
955 self.dbformat_eapi -= 1
956 continue
957 elif not status:
958
959 do_db_update_transfer = None
960 self.dbformat_eapi -= 1
961 continue
962
963 break
964
965 if skip_this_repo:
966 continue
967
968 if self.dbformat_eapi in (1,2,):
969
970 if self.dbformat_eapi == 2 and db_down_status:
971 rc = self.check_downloaded_database(repo, cmethod)
972 if rc != 0:
973
974 self.__remove_repository_files(repo, cmethod)
975 self.syncErrors = True
976 self.Entropy.cycleDone()
977 continue
978
979 if isinstance(do_db_update_transfer,bool) and not do_db_update_transfer:
980 if os.path.isfile(dbfile):
981 try:
982 shutil.move(dbfile,dbfile_old)
983 do_db_update_transfer = True
984 except:
985 pass
986
987
988 unpack_status = self.handle_downloaded_database_unpack(repo, cmethod)
989 if not unpack_status:
990
991 self.__remove_repository_files(repo, cmethod)
992 self.syncErrors = True
993 self.Entropy.cycleDone()
994 continue
995
996 if self.dbformat_eapi == 1 and db_down_status:
997 rc = self.check_downloaded_database(repo, cmethod)
998 if rc != 0:
999
1000 self.__remove_repository_files(repo, cmethod)
1001 self.syncErrors = True
1002 self.Entropy.cycleDone()
1003 if os.path.isfile(dbfile_old):
1004 os.remove(dbfile_old)
1005 continue
1006
1007
1008 if not os.path.isfile(dbfile):
1009 do_db_update_transfer = False
1010 elif os.path.isfile(dbfile) and not do_db_update_transfer and (self.dbformat_eapi != 1):
1011 os.remove(dbfile)
1012
1013 if self.dbformat_eapi == 2:
1014 rc = self.do_eapi2_inject_downloaded_dump(dumpfile, dbfile, cmethod)
1015
1016 if do_db_update_transfer:
1017 self.do_eapi1_eapi2_databases_alignment(dbfile, dbfile_old)
1018 if self.dbformat_eapi == 2:
1019
1020 os.remove(dumpfile)
1021
1022 if rc != 0:
1023
1024 self.__remove_repository_files(repo, cmethod)
1025 self.syncErrors = True
1026 self.Entropy.cycleDone()
1027 if os.path.isfile(dbfile_old):
1028 os.remove(dbfile_old)
1029 continue
1030
1031 if os.path.isfile(dbfile) and os.access(dbfile,os.W_OK):
1032 try:
1033 self.Entropy.setup_default_file_perms(dbfile)
1034 except OSError:
1035 pass
1036
1037
1038 self.dbupdated = True
1039 self.do_standard_items_download(repo)
1040 self.Entropy.update_repository_revision(repo)
1041 if self.Entropy.indexing:
1042 self.do_database_indexing(repo)
1043 def_repoid = self.Entropy.SystemSettings['repositories']['default_repository']
1044 if repo == def_repoid:
1045 try:
1046 self.run_config_files_updates(repo)
1047 except Exception, e:
1048 self.entropyTools.print_traceback()
1049 mytxt = "%s: %s" % (
1050 blue(_("Configuration files update error, not critical, continuing")),
1051 darkred(unicode(e)),
1052 )
1053 self.Entropy.updateProgress(mytxt, importance = 0, type = "info", header = blue(" # "),)
1054 self.updated_repos.add(repo)
1055 self.Entropy.cycleDone()
1056
1057
1058 if os.path.isfile(dbfile_old):
1059 os.remove(dbfile_old)
1060
1061
1062 self.Entropy.close_all_repositories()
1063 self.Entropy.validate_repositories()
1064 self.Entropy.close_all_repositories()
1065
1066
1067 if self.dbupdated:
1068 self.Entropy.generate_cache(
1069 depcache = self.Entropy.xcache,
1070 configcache = False,
1071 client_purge = False,
1072 install_queue = False
1073 )
1074 if self.fetchSecurity:
1075 self.do_update_security_advisories()
1076
1077 if isinstance(self.Entropy.clientDbconn, LocalRepository) and \
1078 self.entropyTools.is_root():
1079 for repo in self.reponames:
1080 dbc = self.Entropy.open_repository(repo)
1081 dbc.clientUpdatePackagesData(self.Entropy.clientDbconn)
1082 self.Entropy.close_all_repositories()
1083
1084 if self.syncErrors:
1085 self.Entropy.updateProgress(
1086 red(_("Something bad happened. Please have a look.")),
1087 importance = 1,
1088 type = "warning",
1089 header = darkred(" @@ ")
1090 )
1091 self.syncErrors = True
1092 self.Entropy.resources_remove_lock()
1093 return 128
1094
1095 if not self.noEquoCheck:
1096 self.check_entropy_updates()
1097
1098 return 0
1099
1101
1102
1103 if etpConst['uid'] != 0:
1104 self.Entropy.updateProgress(
1105 brown(_("Skipping configuration files update, you are not root.")),
1106 importance = 1,
1107 type = "info",
1108 header = blue(" @@ ")
1109 )
1110 return
1111
1112
1113 self._config_updates_make_conf(repo)
1114 self._config_updates_make_profile(repo)
1115
1116
1118
1119
1120 url, repo_make_conf = self._construct_paths("make.conf", repo, None)
1121 system_make_conf = etpConst['spm']['global_make_conf']
1122 make_conf_variables_check = ["CHOST"]
1123
1124 if os.path.isfile(repo_make_conf) and os.access(repo_make_conf,os.R_OK):
1125
1126 if not os.path.isfile(system_make_conf):
1127 self.Entropy.updateProgress(
1128 "%s %s. %s." % (red(system_make_conf),blue(_("does not exist")),blue(_("Overwriting")),),
1129 importance = 1,
1130 type = "info",
1131 header = blue(" @@ ")
1132 )
1133 if os.path.lexists(system_make_conf):
1134 shutil.move(
1135 system_make_conf,
1136 "%s.backup_%s" % (system_make_conf,self.entropyTools.get_random_number(),)
1137 )
1138 shutil.copy2(repo_make_conf,system_make_conf)
1139
1140 elif os.access(system_make_conf,os.W_OK):
1141
1142 repo_f = open(repo_make_conf,"r")
1143 sys_f = open(system_make_conf,"r")
1144 repo_make_c = [x.strip() for x in repo_f.readlines()]
1145 sys_make_c = [x.strip() for x in sys_f.readlines()]
1146 repo_f.close()
1147 sys_f.close()
1148
1149
1150 repo_data = {}
1151 for setting in make_conf_variables_check:
1152 for line in repo_make_c:
1153 if line.startswith(setting+"="):
1154
1155 repo_data[setting] = line
1156
1157
1158 differences = {}
1159
1160 for setting in repo_data:
1161 for idx in range(len(sys_make_c)):
1162 line = sys_make_c[idx]
1163 if line.startswith(setting+"=") and (line != repo_data[setting]):
1164
1165 self.Entropy.updateProgress(
1166 "%s: %s %s. %s." % (
1167 red(system_make_conf), bold(unicode(setting)),
1168 blue(_("variable differs")), red(_("Updating")),
1169 ),
1170 importance = 1,
1171 type = "info",
1172 header = blue(" @@ ")
1173 )
1174 differences[setting] = repo_data[setting]
1175 line = repo_data[setting]
1176 sys_make_c[idx] = line
1177
1178 if differences:
1179
1180 self.Entropy.updateProgress(
1181 "%s: %s." % (red(system_make_conf), blue(_("updating critical variables")),),
1182 importance = 1,
1183 type = "info",
1184 header = blue(" @@ ")
1185 )
1186
1187 shutil.copy2(system_make_conf,"%s.entropy_backup" % (system_make_conf,))
1188
1189 self.Entropy.updateProgress(
1190 "%s: %s." % (
1191 red(system_make_conf), darkgreen("writing changes to disk"),
1192 ),
1193 importance = 1,
1194 type = "info",
1195 header = blue(" @@ ")
1196 )
1197
1198 tmp_make_conf = "%s.entropy_write" % (system_make_conf,)
1199 f = open(tmp_make_conf,"w")
1200 for line in sys_make_c: f.write(line+"\n")
1201 f.flush()
1202 f.close()
1203 shutil.move(tmp_make_conf,system_make_conf)
1204
1205
1206 for var in differences:
1207 try:
1208 myval = '='.join(differences[var].strip().split("=")[1:])
1209 if myval:
1210 if myval[0] in ("'",'"',): myval = myval[1:]
1211 if myval[-1] in ("'",'"',): myval = myval[:-1]
1212 except IndexError:
1213 myval = ''
1214 os.environ[var] = myval
1215
1217 url, repo_make_profile = self._construct_paths("profile.link",
1218 repo, None)
1219 system_make_profile = etpConst['spm']['global_make_profile']
1220 if not (os.path.isfile(repo_make_profile) and \
1221 os.access(repo_make_profile,os.R_OK)):
1222 return
1223
1224 f = open(repo_make_profile,"r")
1225 repo_profile_link_data = f.readline().strip()
1226 f.close()
1227 current_profile_link = ''
1228 if os.path.islink(system_make_profile) and \
1229 os.access(system_make_profile,os.R_OK):
1230
1231 current_profile_link = os.readlink(system_make_profile)
1232
1233 if (repo_profile_link_data != current_profile_link) and \
1234 repo_profile_link_data:
1235
1236 self.Entropy.updateProgress(
1237 "%s: %s %s. %s." % (
1238 red(system_make_profile), blue("link"),
1239 blue(_("differs")), red(_("Updating")),
1240 ),
1241 importance = 1,
1242 type = "info",
1243 header = blue(" @@ ")
1244 )
1245 merge_sfx = ".entropy_merge"
1246 os.symlink(repo_profile_link_data,system_make_profile+merge_sfx)
1247 if self.entropyTools.is_valid_path(system_make_profile+merge_sfx):
1248 os.rename(system_make_profile+merge_sfx,system_make_profile)
1249 else:
1250
1251 self.Entropy.updateProgress(
1252 "%s: %s %s. %s." % (
1253 red(system_make_profile), blue("new link"),
1254 blue(_("does not exist")), red(_("Reverting")),
1255 ),
1256 importance = 1,
1257 type = "info",
1258 header = blue(" @@ ")
1259 )
1260 os.remove(system_make_profile+merge_sfx)
1261
1262
1264 rc = False
1265 if not self.noEquoCheck:
1266 try:
1267 rc, pkg_match = self.Entropy.check_package_update("sys-apps/entropy", deep = True)
1268 except:
1269 pass
1270 if rc:
1271 self.newEquo = True
1272 mytxt = "%s: %s. %s." % (
1273 bold("Equo/Entropy"),
1274 blue(_("a new release is available")),
1275 darkred(_("Mind to install it before any other package")),
1276 )
1277 self.Entropy.updateProgress(
1278 mytxt,
1279 importance = 1,
1280 type = "info",
1281 header = bold(" !!! ")
1282 )
1283
1285
1286 file_to_unpack = etpConst['etpdatabasedump']
1287 if self.dbformat_eapi == 1:
1288 file_to_unpack = etpConst['etpdatabasefile']
1289 mytxt = "%s %s %s" % (red(_("Unpacking database to")),darkgreen(file_to_unpack),red("..."),)
1290 self.Entropy.updateProgress(
1291 mytxt,
1292 importance = 0,
1293 type = "info",
1294 header = "\t"
1295 )
1296
1297 myrc = self.__unpack_downloaded_database(repo, cmethod)
1298 if myrc != 0:
1299 mytxt = "%s %s !" % (red(_("Cannot unpack compressed package")),red(_("Skipping repository")),)
1300 self.Entropy.updateProgress(
1301 mytxt,
1302 importance = 1,
1303 type = "warning",
1304 header = "\t"
1305 )
1306 return False
1307 return True
1308
1309
1311
1312 hashfile = etpConst['etpdatabasehashfile']
1313 downitem = 'ck'
1314 if self.dbformat_eapi == 2:
1315 hashfile = etpConst[cmethod[6]]
1316 downitem = 'dbdumplightck'
1317
1318 mytxt = "%s %s %s" % (red(_("Downloading checksum")),darkgreen(hashfile),red("..."),)
1319
1320 self.Entropy.updateProgress(
1321 mytxt,
1322 importance = 0,
1323 type = "info",
1324 header = "\t"
1325 )
1326
1327 db_down_status = self.download_item(downitem, repo, cmethod, disallow_redirect = True)
1328 if not db_down_status:
1329 mytxt = "%s %s !" % (red(_("Cannot fetch checksum")),red(_("Cannot verify database integrity")),)
1330 self.Entropy.updateProgress(
1331 mytxt,
1332 importance = 1,
1333 type = "warning",
1334 header = "\t"
1335 )
1336 return db_down_status
1337
1344
1346 if self.LockScanner != None:
1347 self.LockScanner.kill()
1348
1350 locked = self.handle_repository_lock(repo)
1351 if locked:
1352 self.current_repository_got_locked = True
1353
1355
1356 if self.current_repository_got_locked:
1357 mytxt = _("Current repository got suddenly locked. Download aborted.")
1358 raise RepositoryError('RepositoryError %s' % (mytxt,))
1359
1361
1362 def show_repo_locked_message():
1363 mytxt = "%s: %s." % (
1364 bold(_("Attention")),
1365 red(_("remote database got suddenly locked")),
1366 )
1367 self.Entropy.updateProgress(
1368 mytxt,
1369 importance = 1,
1370 type = "warning",
1371 header = "\t"
1372 )
1373
1374
1375 mytxt = "%s ..." % (red(_("Downloading repository database")),)
1376 self.Entropy.updateProgress(
1377 mytxt,
1378 importance = 1,
1379 type = "info",
1380 header = "\t"
1381 )
1382
1383 down_status = False
1384 if self.dbformat_eapi == 2:
1385
1386 self.load_background_repository_lock_check(repo)
1387 down_status = self.download_item("dbdumplight", repo, cmethod,
1388 lock_status_func = self.repository_lock_scanner_status,
1389 disallow_redirect = True)
1390 if self.current_repository_got_locked:
1391 self.kill_previous_repository_lock_scanner()
1392 show_repo_locked_message()
1393 return False
1394 if not down_status:
1395
1396 self.load_background_repository_lock_check(repo)
1397 self.dbformat_eapi = 1
1398 down_status = self.download_item("db", repo, cmethod,
1399 lock_status_func = self.repository_lock_scanner_status,
1400 disallow_redirect = True)
1401 if self.current_repository_got_locked:
1402 self.kill_previous_repository_lock_scanner()
1403 show_repo_locked_message()
1404 return False
1405
1406 if not down_status:
1407 mytxt = "%s: %s." % (bold(_("Attention")),red(_("database does not exist online")),)
1408 self.Entropy.updateProgress(
1409 mytxt,
1410 importance = 1,
1411 type = "warning",
1412 header = "\t"
1413 )
1414
1415 self.kill_previous_repository_lock_scanner()
1416 return down_status
1417
1419
1420 update = self.is_repository_updatable(repo)
1421 if not update:
1422 mytxt = "%s: %s." % (bold(_("Attention")),red(_("database is already up to date")),)
1423 self.Entropy.updateProgress(
1424 mytxt,
1425 importance = 1,
1426 type = "info",
1427 header = "\t"
1428 )
1429 return True
1430
1431 if self.dbformat_eapi == 3:
1432 locked = self.is_repository_eapi3_locked(repo)
1433 if locked:
1434 mytxt = "%s: %s." % (bold(_("Attention")),red(_("database will be ready soon")),)
1435 self.Entropy.updateProgress(
1436 mytxt,
1437 importance = 1,
1438 type = "info",
1439 header = "\t"
1440 )
1441 return True
1442 return False
1443
1445
1446 unlocked = self.is_repository_unlocked(repo)
1447 if not unlocked:
1448 mytxt = "%s: %s. %s." % (
1449 bold(_("Attention")),
1450 red(_("Repository is being updated")),
1451 red(_("Try again in a few minutes")),
1452 )
1453 self.Entropy.updateProgress(
1454 mytxt,
1455 importance = 1,
1456 type = "warning",
1457 header = "\t"
1458 )
1459 return True
1460 return False
1461
1463
1464 dbconn = self.Entropy.open_generic_database(dbfile, xcache = False, indexing_override = False)
1465 old_dbconn = self.Entropy.open_generic_database(dbfile_old, xcache = False, indexing_override = False)
1466 upd_rc = 0
1467 try:
1468 upd_rc = old_dbconn.alignDatabases(dbconn, output_header = "\t")
1469 except (self.dbapi2.OperationalError, self.dbapi2.IntegrityError,
1470 self.dbapi2.DatabaseError,):
1471 pass
1472 old_dbconn.closeDB()
1473 dbconn.closeDB()
1474 if upd_rc > 0:
1475
1476
1477 shutil.move(dbfile_old,dbfile)
1478 return upd_rc
1479
1481
1482
1483 mytxt = "%s %s, %s %s" % (
1484 red(_("Injecting downloaded dump")),
1485 darkgreen(etpConst[cmethod[5]]),
1486 red(_("please wait")),
1487 red("..."),
1488 )
1489 self.Entropy.updateProgress(
1490 mytxt,
1491 importance = 0,
1492 type = "info",
1493 header = "\t"
1494 )
1495 dbconn = self.Entropy.open_generic_database(dbfile, xcache = False, indexing_override = False)
1496 rc = dbconn.doDatabaseImport(dumpfile, dbfile)
1497 dbconn.closeDB()
1498 return rc
1499
1500
1502
1503 try:
1504 securityConn = self.Entropy.Security()
1505 securityConn.fetch_advisories()
1506 except Exception, e:
1507 self.entropyTools.print_traceback(f = self.Entropy.clientLog)
1508 mytxt = "%s: %s" % (red(_("Advisories fetch error")),e,)
1509 self.Entropy.updateProgress(
1510 mytxt,
1511 importance = 1,
1512 type = "warning",
1513 header = darkred(" @@ ")
1514 )
1515
1517
1518 g_make_conf = os.path.basename(etpConst['spm']['global_make_conf'])
1519 pkg_unmask = os.path.basename(etpConst['spm']['global_package_unmask'])
1520 pkg_keywords = os.path.basename(etpConst['spm']['global_package_keywords'])
1521 pkg_use = os.path.basename(etpConst['spm']['global_package_use'])
1522 profile_link = etpConst['spm']['global_make_profile_link_name']
1523 notice_board = os.path.basename(self.Entropy.SystemSettings['repositories']['available'][repo]['local_notice_board'])
1524
1525 objects_to_unpack = ("meta_file",)
1526
1527 download_items = [
1528 (
1529 "meta_file",
1530 etpConst['etpdatabasemetafilesfile'],
1531 True,
1532 "%s %s %s" % (
1533 red(_("Downloading repository metafile")),
1534 darkgreen(etpConst['etpdatabasemetafilesfile']),
1535 red("..."),
1536 )
1537 ),
1538 (
1539 "ca.cert",
1540 etpConst['etpdatabasecacertfile'],
1541 True,
1542 "%s %s %s" % (
1543 red(_("Downloading SSL CA certificate")),
1544 darkgreen(etpConst['etpdatabasecacertfile']),
1545 red("..."),
1546 )
1547 ),
1548 (
1549 "server.cert",
1550 etpConst['etpdatabaseservercertfile'],
1551 True,
1552 "%s %s %s" % (
1553 red(_("Downloading SSL Server certificate")),
1554 darkgreen(etpConst['etpdatabaseservercertfile']),
1555 red("..."),
1556 )
1557 ),
1558 (
1559 "mask",
1560 etpConst['etpdatabasemaskfile'],
1561 True,
1562 "%s %s %s" % (
1563 red(_("Downloading package mask")),
1564 darkgreen(etpConst['etpdatabasemaskfile']),
1565 red("..."),
1566 )
1567 ),
1568 (
1569 "system_mask",
1570 etpConst['etpdatabasesytemmaskfile'],
1571 True,
1572 "%s %s %s" % (
1573 red(_("Downloading packages system mask")),
1574 darkgreen(etpConst['etpdatabasesytemmaskfile']),
1575 red("..."),
1576 )
1577 ),
1578 (
1579 "conflicting_tagged",
1580 etpConst['etpdatabaseconflictingtaggedfile'],
1581 True,
1582 "%s %s %s" % (
1583 red(_("Downloading conflicting tagged packages file")),
1584 darkgreen(etpConst['etpdatabaseconflictingtaggedfile']),
1585 red("..."),
1586 )
1587 ),
1588 (
1589 "lic_whitelist",
1590 etpConst['etpdatabaselicwhitelistfile'],
1591 True,
1592 "%s %s %s" % (
1593 red(_("Downloading license whitelist")),
1594 darkgreen(etpConst['etpdatabaselicwhitelistfile']),
1595 red("..."),
1596 )
1597 ),
1598 (
1599 "rev",
1600 etpConst['etpdatabaserevisionfile'],
1601 False,
1602 "%s %s %s" % (
1603 red(_("Downloading revision")),
1604 darkgreen(etpConst['etpdatabaserevisionfile']),
1605 red("..."),
1606 )
1607 ),
1608 (
1609 "make.conf",
1610 g_make_conf,
1611 True,
1612 "%s %s %s" % (
1613 red(_("Downloading SPM global configuration")),
1614 darkgreen(g_make_conf),
1615 red("..."),
1616 )
1617 ),
1618 (
1619 "package.unmask",
1620 pkg_unmask,
1621 True,
1622 "%s %s %s" % (
1623 red(_("Downloading SPM package unmasking configuration")),
1624 darkgreen(pkg_unmask),
1625 red("..."),
1626 )
1627 ),
1628 (
1629 "package.keywords",
1630 pkg_keywords,
1631 True,
1632 "%s %s %s" % (
1633 red(_("Downloading SPM package keywording configuration")),
1634 darkgreen(pkg_keywords),
1635 red("..."),
1636 )
1637 ),
1638 (
1639 "package.use",
1640 pkg_use,
1641 True,
1642 "%s %s %s" % (
1643 red(_("Downloading SPM package USE flags configuration")),
1644 darkgreen(pkg_use),
1645 red("..."),
1646 )
1647 ),
1648 (
1649 "profile.link",
1650 profile_link,
1651 True,
1652 "%s %s %s" % (
1653 red(_("Downloading SPM Profile configuration")),
1654 darkgreen(profile_link),
1655 red("..."),
1656 )
1657 ),
1658 (
1659 "notice_board",
1660 notice_board,
1661 True,
1662 "%s %s %s" % (
1663 red(_("Downloading Notice Board")),
1664 darkgreen(notice_board),
1665 red("..."),
1666 )
1667 )
1668 ]
1669
1670 def my_show_info(txt):
1671 self.Entropy.updateProgress(
1672 txt,
1673 importance = 0,
1674 type = "info",
1675 header = "\t",
1676 back = True
1677 )
1678
1679 def my_show_down_status(message, mytype):
1680 self.Entropy.updateProgress(
1681 message,
1682 importance = 0,
1683 type = mytype,
1684 header = "\t"
1685 )
1686
1687 def my_show_file_unpack(fp):
1688 self.Entropy.updateProgress(
1689 "%s: %s" % (darkgreen(_("unpacked meta file")),brown(fp),),
1690 header = blue(u"\t << ")
1691 )
1692
1693 downloaded_by_unpack = set()
1694 for item, myfile, ignorable, mytxt in download_items:
1695
1696
1697 if myfile in downloaded_by_unpack: continue
1698
1699 my_show_info(mytxt)
1700 mystatus = self.download_item(item, repo, disallow_redirect = True)
1701 mytype = 'info'
1702
1703
1704 if not mystatus:
1705 if ignorable:
1706 message = "%s: %s." % (blue(myfile),red(_("not available, it's ok")))
1707 else:
1708 mytype = 'warning'
1709 message = "%s: %s." % (blue(myfile),darkred(_("not available, not much ok!")))
1710 my_show_down_status(message, mytype)
1711 continue
1712
1713 myurl, mypath = self._construct_paths(item, repo, None)
1714 message = "%s: %s." % (blue(myfile),darkgreen(_("available, w00t!")))
1715 my_show_down_status(message, mytype)
1716 if item not in objects_to_unpack: continue
1717 if not (os.path.isfile(mypath) and os.access(mypath,os.R_OK)): continue
1718
1719 while 1:
1720 tmpdir = os.path.join(os.path.dirname(mypath),"meta_unpack_%s" % (random.randint(1,10000),))
1721 if not os.path.lexists(tmpdir): break
1722 os.makedirs(tmpdir,0775)
1723
1724 repo_dir = self.Entropy.SystemSettings['repositories']['available'][repo]['dbpath']
1725 try:
1726 done = self.entropyTools.universal_uncompress(mypath, tmpdir, catch_empty = True)
1727 if not done: continue
1728 myfiles_to_move = set(os.listdir(tmpdir))
1729
1730
1731 files_not_found_file = etpConst['etpdatabasemetafilesnotfound']
1732 if files_not_found_file in myfiles_to_move:
1733 myfiles_to_move.remove(files_not_found_file)
1734 try:
1735 with open(os.path.join(tmpdir,files_not_found_file),"r") as f:
1736 f_nf = [x.strip() for x in f.readlines()]
1737 downloaded_by_unpack |= set(f_nf)
1738 except IOError:
1739 pass
1740
1741 for myfile in sorted(myfiles_to_move):
1742 from_mypath = os.path.join(tmpdir,myfile)
1743 to_mypath = os.path.join(repo_dir,myfile)
1744 try:
1745 os.rename(from_mypath,to_mypath)
1746 downloaded_by_unpack.add(myfile)
1747 my_show_file_unpack(myfile)
1748 except OSError:
1749 continue
1750
1751 finally:
1752
1753 shutil.rmtree(tmpdir,True)
1754 try: os.rmdir(tmpdir)
1755 except OSError: pass
1756
1757
1758 mytxt = "%s: %s" % (
1759 red(_("Repository revision")),
1760 bold(str(self.Entropy.get_repository_revision(repo))),
1761 )
1762 self.Entropy.updateProgress(
1763 mytxt,
1764 importance = 1,
1765 type = "info",
1766 header = "\t"
1767 )
1768
1769
1770
1772
1773
1774 old_prio = self.Entropy.set_priority(15)
1775 mytxt = red("%s ...") % (_("Indexing Repository metadata"),)
1776 self.Entropy.updateProgress(
1777 mytxt,
1778 importance = 1,
1779 type = "info",
1780 header = "\t",
1781 back = True
1782 )
1783 dbconn = self.Entropy.open_repository(repo)
1784 dbconn.createAllIndexes()
1785
1786 repo_indexes = dbconn.listAllIndexes()
1787 if self.Entropy.clientDbconn != None:
1788 try:
1789 client_indexes = self.Entropy.clientDbconn.listAllIndexes()
1790 if repo_indexes != client_indexes:
1791 self.Entropy.clientDbconn.createAllIndexes()
1792 except:
1793 pass
1794 self.Entropy.set_priority(old_prio)
1795
1796
1838