Package entropy :: Module const

Source Code for Module entropy.const

   1  """ 
   2   
   3      @author: Fabio Erculiani <lxnay@sabayonlinux.org> 
   4      @contact: lxnay@sabayonlinux.org 
   5      @copyright: Fabio Erculiani 
   6      @license: GPL-2 
   7   
   8      B{Entropy Framework constants module}. 
   9   
  10      This module contains all the Entropy constants used all around 
  11      the "entropy" package. 
  12   
  13      Some of the constants in this module are used as "default" for 
  14      the SystemSettings interface. So, make sure to read the documentation 
  15      of SystemSettings in the "entropy.core" module. 
  16   
  17      Even if possible, etpConst, etpUi, etpCache and etpSys objects 
  18      *SHOULD* be I{never ever modified manually}. This freedom could change 
  19      in future, so, if you want to produce a stable code, DON'T do that at all! 
  20   
  21      Basic Entropy constants handling functions are available in this module 
  22      and are all prefixed with "I{const_*}" or "I{initconfig_*}". 
  23      If you are writing a third party application, you should always try 
  24      to avoid to deal directly with functions here unless specified otherwise. 
  25      In fact, usually these here are wrapper in upper-level modules 
  26      (entropy.client, entropy.server, entropy.services). 
  27   
  28   
  29  """ 
  30   
  31   
  32  from __future__ import with_statement 
  33  import sys, os, stat 
  34  from entropy.i18n import _ 
  35  import gzip 
  36  import bz2 
  37   
  38  # ETP_ARCH_CONST setup 
  39  ETP_ARCH_CONST = "x86" 
  40  if os.uname()[4] == "x86_64": 
  41      ETP_ARCH_CONST = "amd64" 
  42   
  43  etpSys = { 
  44      'archs': ["x86", "amd64"], 
  45      'keywords': set([ETP_ARCH_CONST,"~"+ETP_ARCH_CONST]), 
  46      'api': '3', 
  47      'arch': ETP_ARCH_CONST, 
  48      'rootdir': "", 
  49      'maxthreads': 100, 
  50      'dirstoclean': set(), 
  51      'serverside': False, 
  52      'killpids': set(), 
  53  } 
  54   
  55  etpUi = { 
  56      'debug': False, 
  57      'quiet': False, 
  58      'verbose': False, 
  59      'ask': False, 
  60      'pretend': False, 
  61      'mute': False, 
  62      'nolog': False, 
  63      'clean': False, 
  64      'warn': True, 
  65  } 
  66  if "--debug" in sys.argv: 
  67      etpUi['debug'] = True 
  68   
  69  # static logging stuff 
  70  ETP_LOGLEVEL_NORMAL = 1 
  71  ETP_LOGLEVEL_VERBOSE = 2 
  72  ETP_LOGPRI_INFO = "[ INFO ]" 
  73  ETP_LOGPRI_WARNING = "[ WARNING ]" 
  74  ETP_LOGPRI_ERROR = "[ ERROR ]" 
  75   
  76  # disk caching dictionary 
  77  etpCache = { 
  78      # used to store information about files that 
  79      # should be merged using "equo conf merge" 
  80      'configfiles': 'conf/scanfs', 
  81      'dbMatch': 'match/db', # db atom match cache 
  82      'dbSearch': 'search/db', # db search cache 
  83      # used to store info about repository dependencies solving 
  84      'atomMatch': 'atom_match/atom_match_', 
  85      'install': 'resume/resume_install', # resume cache (install) 
  86      'remove': 'resume/resume_remove', # resume cache (remove) 
  87      'world': 'resume/resume_world', # resume cache (world) 
  88      'world_update': 'world_update/world_cache_', 
  89      'critical_update': 'critical_update/critical_cache_', 
  90      'world_available': 'world_available/available_cache_', 
  91      'check_package_update': 'check_update/package_update_', 
  92      'advisories': 'security/advisories_cache_', 
  93      'dep_tree': 'deptree/dep_tree_', 
  94      'depends_tree': 'depends/depends_tree_', 
  95      'filter_satisfied_deps': 'depfilter/filter_satisfied_deps_', 
  96      'library_breakage': 'libs_break/library_breakage_', 
  97      'repolist': 'repos/repolist', 
  98      'repository_server': 'reposerver/item', 
  99      'eapi3_fetch': 'eapi3/segment_', 
 100      'ugc_votes': 'ugc/ugc_votes', 
 101      'ugc_downloads': 'ugc/ugc_downloads', 
 102      'ugc_docs': 'ugc/ugc_docs', 
 103      'ugc_srv_cache': 'ugc/ugc_srv_cache' 
 104  } 
 105   
 106  etpConst = {} 
 107   
108 -def initconfig_entropy_constants(rootdir):
109 110 """ 111 Main constants configurators, this is the only function that you should 112 call from the outside, anytime you want. it will reset all the variables 113 excluding those backed up previously. 114 115 @param rootdir: current root directory, if any, or "" 116 @type rootdir: string 117 @rtype: None 118 @return: None 119 @raise AttributeError: when specified rootdir is not a directory 120 """ 121 122 if rootdir and not os.path.isdir(rootdir): 123 raise AttributeError("not a valid chroot.") 124 125 # save backed up settings 126 if etpConst.has_key('backed_up'): 127 backed_up_settings = etpConst.pop('backed_up') 128 else: 129 backed_up_settings = {} 130 131 const_default_settings(rootdir) 132 const_read_entropy_release() 133 const_create_working_dirs() 134 const_setup_entropy_pid() 135 const_configure_lock_paths() 136 137 # reflow back settings 138 etpConst.update(backed_up_settings) 139 etpConst['backed_up'] = backed_up_settings.copy() 140 141 if sys.excepthook == sys.__excepthook__: 142 sys.excepthook = __const_handle_exception
143
144 -def const_default_settings(rootdir):
145 146 """ 147 Initialization of all the Entropy base settings. 148 149 @param rootdir: current root directory, if any, or "" 150 @type rootdir: string 151 @rtype: None 152 @return: None 153 """ 154 155 default_etp_dir = rootdir+"/var/lib/entropy" 156 default_etp_tmpdir = "/tmp" 157 default_etp_repodir = "/packages/"+ETP_ARCH_CONST 158 default_etp_portdir = rootdir+"/usr/portage" 159 default_etp_distfilesdir = "/distfiles" 160 default_etp_dbdir = "/database/"+ETP_ARCH_CONST 161 default_etp_dbfile = "packages.db" 162 default_etp_dbclientfile = "equo.db" 163 default_etp_client_repodir = "/client" 164 default_etp_triggersdir = "/triggers/"+ETP_ARCH_CONST 165 default_etp_smartappsdir = "/smartapps/"+ETP_ARCH_CONST 166 default_etp_smartpackagesdir = "/smartpackages/"+ETP_ARCH_CONST 167 default_etp_cachesdir = "/caches/" 168 default_etp_securitydir = "/glsa/" 169 default_etp_setsdirname = "sets" 170 default_etp_setsdir = "/%s/" % (default_etp_setsdirname,) 171 default_etp_logdir = default_etp_dir+"/"+"logs" 172 default_etp_confdir = rootdir+"/etc/entropy" 173 default_etp_packagesdir = default_etp_confdir+"/packages" 174 default_etp_ugc_confdir = default_etp_confdir+"/ugc" 175 default_etp_syslogdir = rootdir+"/var/log/entropy/" 176 default_etp_vardir = rootdir+"/var/tmp/entropy" 177 edb_counter = rootdir+"/var/cache/edb/counter" 178 179 cmdline = [] 180 cmdline_file = "/proc/cmdline" 181 if os.access(cmdline_file, os.R_OK) and os.path.isfile(cmdline_file): 182 with open(cmdline_file, "r") as cmdline_f: 183 cmdline = cmdline_f.readline().strip().split() 184 185 etpConst.clear() 186 my_const = { 187 'server_repositories': {}, 188 'community': { 189 'mode': False, 190 }, 191 'cmdline': cmdline, 192 'backed_up': {}, 193 # entropy default installation directory 194 'installdir': '/usr/lib/entropy', 195 # etpConst['packagestmpdir'] --> temp directory 196 'packagestmpdir': default_etp_dir+default_etp_tmpdir, 197 # etpConst['packagesbindir'] --> repository 198 # where the packages will be stored 199 # by clients: to query if a package has been already downloaded 200 # by servers or rsync mirrors: to store already 201 # uploaded packages to the main rsync server 202 'packagesbindir': default_etp_dir+default_etp_repodir, 203 # etpConst['smartappsdir'] location where smart apps files are places 204 'smartappsdir': default_etp_dir+default_etp_smartappsdir, 205 # etpConst['smartpackagesdir'] location where 206 # smart packages files are places 207 'smartpackagesdir': default_etp_dir+default_etp_smartpackagesdir, 208 # etpConst['triggersdir'] location where external triggers are placed 209 'triggersdir': default_etp_dir+default_etp_triggersdir, 210 # directory where is stored our local portage tree 211 'portagetreedir': default_etp_portdir, 212 # directory where our sources are downloaded 213 'distfilesdir': default_etp_portdir+default_etp_distfilesdir, 214 # directory where entropy stores its configuration 215 'confdir': default_etp_confdir, 216 # same as above + /packages 217 'confpackagesdir': default_etp_packagesdir, 218 # system package sets dir 219 'confsetsdir': default_etp_packagesdir+default_etp_setsdir, 220 # just the dirname 221 'confsetsdirname': default_etp_setsdirname, 222 # entropy.conf file 223 'entropyconf': default_etp_confdir+"/entropy.conf", 224 # repositories.conf file 225 'repositoriesconf': default_etp_confdir+"/repositories.conf", 226 # server.conf file (generic server side settings) 227 'serverconf': default_etp_confdir+"/server.conf", 228 # client.conf file (generic entropy client side settings) 229 'clientconf': default_etp_confdir+"/client.conf", 230 # socket.conf file 231 'socketconf': default_etp_confdir+"/socket.conf", 232 # user by client interfaces 233 'packagesrelativepath': "packages/"+ETP_ARCH_CONST+"/", 234 235 'entropyworkdir': default_etp_dir, # Entropy workdir 236 # Entropy unpack directory 237 'entropyunpackdir': default_etp_vardir, 238 # Entropy packages image directory 239 'entropyimagerelativepath': "image", 240 # Gentoo xpak temp directory path 241 'entropyxpakrelativepath': "xpak", 242 # Gentoo xpak metadata directory path 243 'entropyxpakdatarelativepath': "data", 244 # Gentoo xpak metadata file name 245 'entropyxpakfilename': "metadata.xpak", 246 247 # entropy repository database upload timestamp 248 'etpdatabasetimestampfile': default_etp_dbfile+".timestamp", 249 # entropy repository database owned (in repo) package files 250 'etpdatabasepkglist': default_etp_dbfile+".pkglist", 251 'etpdatabaseconflictingtaggedfile': default_etp_dbfile + \ 252 ".conflicting_tagged", 253 # file containing a list of packages that are strictly 254 # required by the repository, thus forced 255 'etpdatabasesytemmaskfile': default_etp_dbfile+".system_mask", 256 'etpdatabasemaskfile': default_etp_dbfile+".mask", 257 'etpdatabaseupdatefile': default_etp_dbfile+".repo_updates", 258 'etpdatabaselicwhitelistfile': default_etp_dbfile+".lic_whitelist", 259 'etpdatabasecriticalfile': default_etp_dbfile+".critical", 260 # the local/remote database revision file 261 'etpdatabaserevisionfile': default_etp_dbfile+".revision", 262 # missing dependencies black list file 263 'etpdatabasemissingdepsblfile': default_etp_dbfile + \ 264 ".missing_deps_blacklist", 265 # compressed file that contains all the "meta" 266 # files in a repository dir 267 'etpdatabasemetafilesfile': default_etp_dbfile+".meta", 268 # file that contains a list of the "meta" 269 # files not available in the repository 270 'etpdatabasemetafilesnotfound': default_etp_dbfile+".meta_notfound", 271 'etpdatabasehashfile': default_etp_dbfile+".md5", # its checksum 272 273 274 # the remote database lock file 275 'etpdatabaselockfile': default_etp_dbfile+".lock", 276 # the remote database lock file 277 'etpdatabaseeapi3lockfile': default_etp_dbfile+".eapi3_lock", 278 # the remote database download lock file 279 'etpdatabasedownloadlockfile': default_etp_dbfile+".download.lock", 280 'etpdatabasecacertfile': "ca.cert", 281 'etpdatabaseservercertfile': "server.cert", 282 # when this file exists, the database is not synced 283 # anymore with the online one 284 'etpdatabasetaintfile': default_etp_dbfile+".tainted", 285 286 # Entropy sqlite database file default_etp_dir + \ 287 # default_etp_dbdir+"/packages.db" 288 'etpdatabasefile': default_etp_dbfile, 289 # Entropy sqlite database file (gzipped) 290 'etpdatabasefilegzip': default_etp_dbfile+".gz", 291 # Entropy sqlite database file (bzipped2) 292 'etpdatabasefilebzip2': default_etp_dbfile+".bz2", 293 294 # Entropy sqlite database file (gzipped) 295 'etpdatabasefilegziplight': default_etp_dbfile+".light.gz", 296 'etpdatabasefilehashgziplight': default_etp_dbfile+".light.gz.md5", 297 # Entropy sqlite database file (bzipped2) 298 'etpdatabasefilebzip2light': default_etp_dbfile+".light.bz2", 299 'etpdatabasefilehashbzip2light': default_etp_dbfile+".light.bz2.md5", 300 301 # Entropy sqlite database dump file (bzipped2) 302 'etpdatabasedumpbzip2': default_etp_dbfile+".dump.bz2", 303 'etpdatabasedumphashfilebz2': default_etp_dbfile+".dump.bz2.md5", 304 # Entropy sqlite database dump file (gzipped) 305 'etpdatabasedumpgzip': default_etp_dbfile+".dump.gz", 306 'etpdatabasedumphashfilegzip': default_etp_dbfile+".dump.gz.md5", 307 308 # Entropy sqlite database dump file 309 'etpdatabasedump': default_etp_dbfile+".dump", 310 311 # Entropy sqlite database dump file (bzipped2) light ver 312 'etpdatabasedumplightbzip2': default_etp_dbfile+".dumplight.bz2", 313 # Entropy sqlite database dump file (gzipped) light ver 314 'etpdatabasedumplightgzip': default_etp_dbfile+".dumplight.gz", 315 # Entropy sqlite database dump file, light ver (no content) 316 'etpdatabasedumplighthashfilebz2': default_etp_dbfile+".dumplight.bz2.md5", 317 'etpdatabasedumplighthashfilegzip': default_etp_dbfile+".dumplight.gz.md5", 318 'etpdatabasedumplight': default_etp_dbfile+".dumplight", 319 # expiration based server-side packages removal 320 321 'etpdatabaseexpbasedpkgsrm': default_etp_dbfile+".fatscope", 322 323 # Entropy default compressed database format 324 'etpdatabasefileformat': "bz2", 325 # Entropy compressed databases format support 326 'etpdatabasesupportedcformats': ["bz2", "gz"], 327 'etpdatabasecompressclasses': { 328 "bz2": (bz2.BZ2File, "unpack_bzip2", "etpdatabasefilebzip2", 329 "etpdatabasedumpbzip2", "etpdatabasedumphashfilebz2", 330 "etpdatabasedumplightbzip2", "etpdatabasedumplighthashfilebz2", 331 "etpdatabasefilebzip2light","etpdatabasefilehashbzip2light",), 332 "gz": (gzip.GzipFile, "unpack_gzip", "etpdatabasefilegzip", 333 "etpdatabasedumpgzip", "etpdatabasedumphashfilegzip", 334 "etpdatabasedumplightgzip", "etpdatabasedumplighthashfilegzip", 335 "etpdatabasefilegziplight","etpdatabasefilehashgziplight",) 336 }, 337 # enable/disable packages RSS feed feature 338 'rss-feed': True, 339 # default name of the RSS feed 340 'rss-name': "packages.rss", 341 'rss-light-name': "updates.rss", # light version 342 # default URL to the entropy web interface 343 # (overridden in reagent.conf) 344 'rss-base-url': "http://packages.sabayonlinux.org/", 345 # default URL to the Operating System website 346 # (overridden in reagent.conf) 347 'rss-website-url': "http://www.sabayonlinux.org/", 348 # xml file where will be dumped ServerInterface.rssMessages dictionary 349 'rss-dump-name': "rss_database_actions", 350 'rss-max-entries': 10000, # maximum rss entries 351 'rss-light-max-entries': 300, # max entries for the light version 352 'rss-managing-editor': "lxnay@sabayonlinux.org", # updates submitter 353 # repository RSS-based notice board content 354 'rss-notice-board': "notice.rss", 355 356 'packagesetprefix': "@", 357 'userpackagesetsid': "__user__", 358 'setsconffilename': "sets.conf", 359 'cachedumpext': ".dmp", 360 'packagesext': ".tbz2", 361 'smartappsext': ".esa", 362 # Extension of the file that contains the checksum 363 # of its releated package file 364 'packagesmd5fileext': ".md5", 365 'packagessha512fileext': ".sha512", 366 'packagessha256fileext': ".sha256", 367 'packagessha1fileext': ".sha1", 368 # Extension of the file that "contains" expiration mtime 369 'packagesexpirationfileext': ".expired", 370 # number of days after a package will be removed from mirrors 371 'packagesexpirationdays': 15, 372 # name of the trigger file that would be executed 373 # by equo inside triggerTools 374 'triggername': "trigger", 375 'trigger_sh_interpreter': rootdir+"/usr/sbin/entropy.sh", 376 # entropy hardware hash generator executable 377 'etp_hw_hash_gen': rootdir+"/usr/bin/entropy_hwgen.sh", 378 # entropy client post valid branch migration (equo hop) script name 379 'etp_post_branch_hop_script': default_etp_dbfile+".post_branch.sh", 380 # entropy client post branch upgrade script 381 'etp_post_branch_upgrade_script': default_etp_dbfile+".post_upgrade.sh", 382 # proxy configuration constants, used system wide 383 'etp_post_branch_hop_status_file': ".branch_hop", 384 'etp_post_branch_upgrade_status_file': ".branch_upgraded", 385 'etp_previous_branch_file': default_etp_confdir+"/.previous_branch", 386 387 'proxy': { 388 'ftp': None, 389 'http': None, 390 'username': None, 391 'password': None 392 }, 393 # Entropy log level (default: 1 - see entropy.conf for more info) 394 'entropyloglevel': 1, 395 # Entropy Socket Interface log level 396 'socketloglevel': 2, 397 'spmloglevel': 1, 398 # Log dir where ebuilds store their stuff 399 'logdir': default_etp_logdir, 400 401 'syslogdir': default_etp_syslogdir, # Entropy system tools log directory 402 'entropylogfile': default_etp_syslogdir+"entropy.log", 403 'equologfile': default_etp_syslogdir+"equo.log", 404 'spmlogfile': default_etp_syslogdir+"spm.log", 405 'socketlogfile': default_etp_syslogdir+"socket.log", 406 407 'etpdatabaseclientdir': default_etp_dir + default_etp_client_repodir + \ 408 default_etp_dbdir, 409 # path to equo.db - client side database file 410 'etpdatabaseclientfilepath': default_etp_dir + \ 411 default_etp_client_repodir + default_etp_dbdir + "/" + \ 412 default_etp_dbclientfile, 413 # prefix of the name of self.dbname in 414 # entropy.db.LocalRepository class for the repositories 415 'dbnamerepoprefix': "repo_", 416 # prefix of database backups 417 'dbbackupprefix': 'etp_backup_', 418 419 # Entropy database API revision 420 'etpapi': etpSys['api'], 421 # contains the current running architecture 422 'currentarch': etpSys['arch'], 423 # Entropy supported Archs 424 'supportedarchs': etpSys['archs'], 425 426 # default choosen branch (overridden by setting in repositories.conf) 427 'branch': "4", 428 # default allowed package keywords 429 'keywords': etpSys['keywords'].copy(), 430 # allow multiple packages in single scope server-side? 431 # this makes possible to have multiple versions of packages 432 # and handle the removal through expiration (using creation date) 433 'expiration_based_scope': False, 434 'edbcounter': edb_counter, 435 'libtest_blacklist': [], 436 'libtest_files_blacklist': [], 437 # our official repository name 438 'officialserverrepositoryid': "sabayonlinux.org", 439 # our official repository name 440 'officialrepositoryid': "sabayonlinux.org", 441 'conntestlink': "http://www.sabayonlinux.org", 442 # tag to append to .tbz2 file before entropy database (must be 32bytes) 443 'databasestarttag': "|ENTROPY:PROJECT:DB:MAGIC:START|", 444 'pidfile': default_etp_dir+"/entropy.lock", 445 'applicationlock': False, 446 # option to keep a backup of config files after 447 # being overwritten by equo conf update 448 'filesbackup': True, 449 # option to enable forced installation of critical updates 450 'forcedupdates': True, 451 # collision protection option, see client.conf for more info 452 'collisionprotect': 1, 453 # list of user specified CONFIG_PROTECT directories 454 # (see Gentoo manual to understand the meaining of this parameter) 455 'configprotect': [], 456 # list of user specified CONFIG_PROTECT_MASK directories 457 'configprotectmask': [], 458 # list of user specified configuration files that 459 # should be ignored and kept as they are 460 'configprotectskip': [], 461 # installed database CONFIG_PROTECT directories 462 'dbconfigprotect': [], 463 # installed database CONFIG_PROTECT_MASK directories 464 'dbconfigprotectmask': [], 465 # this will be used to show the number of updated 466 # files at the end of the processes 467 'configprotectcounter': 0, 468 # default Entropy release version 469 'entropyversion': "1.0", 470 # default system name (overidden by entropy.conf settings) 471 'systemname': "Sabayon Linux", 472 # Product identificator (standard, professional...) 473 'product': "standard", 474 'errorstatus': default_etp_confdir+"/code", 475 'systemroot': rootdir, # default system root 476 'uid': os.getuid(), # current running UID 477 'entropygid': None, 478 'sysgroup': "entropy", 479 'defaultumask': 022, 480 'storeumask': 002, 481 'gentle_nice': 15, 482 'current_nice': 0, 483 'default_nice': 0, 484 'server_treeupdatescalled': set(), 485 'client_treeupdatescalled': set(), 486 'spm': { 487 '(r)depend_id': 0, 488 'pdepend_id': 1, 489 'mdepend_id': 2, # actually, this is entropy-only 490 'ebuild_file_extension': "ebuild", 491 'preinst_phase': "preinst", 492 'postinst_phase': "postinst", 493 'prerm_phase': "prerm", 494 'postrm_phase': "postrm", 495 'setup_phase': "setup", 496 'compile_phase': "compile", 497 'install_phase': "install", 498 'unpack_phase': "unpack", 499 'ebuild_pkg_tag_var': "ENTROPY_PROJECT_TAG", 500 'global_make_conf': rootdir+"/etc/make.conf", 501 'global_package_keywords': rootdir+"/etc/portage/package.keywords", 502 'global_package_use': rootdir+"/etc/portage/package.use", 503 'global_package_mask': rootdir+"/etc/portage/package.mask", 504 'global_package_unmask': rootdir+"/etc/portage/package.unmask", 505 'global_make_profile': rootdir+"/etc/make.profile", 506 'global_make_profile_link_name' : "profile.link", 507 # source package manager executable 508 'exec': rootdir+"/usr/bin/emerge", 509 'env_update_cmd': rootdir+"/usr/sbin/env-update", 510 'source_profile': ["source", rootdir+"/etc/profile"], 511 'source_build_ext': ".ebuild", 512 'ask_cmd': "--ask", 513 'info_cmd': "--info", 514 'remove_cmd': "-C", 515 'nodeps_cmd': "--nodeps", 516 'fetchonly_cmd': "--fetchonly", 517 'buildonly_cmd': "--buildonly", 518 'oneshot_cmd': "--oneshot", 519 'pretend_cmd': "--pretend", 520 'verbose_cmd': "--verbose", 521 'nocolor_cmd': "--color=n", 522 'backend': "portage", 523 'available_backends': ["portage"], 524 'cache': {}, 525 'xpak_entries': { 526 'description': "DESCRIPTION", 527 'homepage': "HOMEPAGE", 528 'chost': "CHOST", 529 'category': "CATEGORY", 530 'cflags': "CFLAGS", 531 'cxxflags': "CXXFLAGS", 532 'license': "LICENSE", 533 'src_uri': "SRC_URI", 534 'use': "USE", 535 'iuse': "IUSE", 536 'slot': "SLOT", 537 'provide': "PROVIDE", 538 'depend': "DEPEND", 539 'rdepend': "RDEPEND", 540 'pdepend': "PDEPEND", 541 'needed': "NEEDED", 542 'inherited': "INHERITED", 543 'keywords': "KEYWORDS", 544 'contents': "CONTENTS", 545 'counter': "COUNTER", 546 'defined_phases': "DEFINED_PHASES", 547 'pf': "PF", 548 }, 549 'system_packages': [], 550 'ignore-spm-downgrades': False, 551 }, 552 553 # entropy client packages download speed limit (in kb/sec) 554 'downloadspeedlimit': None, 555 556 # data storage directory, useful to speed up 557 # entropy client across multiple issued commands 558 'dumpstoragedir': default_etp_dir+default_etp_cachesdir, 559 # where GLSAs are stored 560 'securitydir': default_etp_dir+default_etp_securitydir, 561 'securityurl': "http://community.sabayonlinux.org/security" 562 "/security-advisories.tar.bz2", 563 564 'safemodeerrors': { 565 'clientdb': 1, 566 }, 567 'safemodereasons': { 568 0: _("All fine"), 569 1: _("Corrupted Client Repository. Please restore a backup."), 570 }, 571 572 'misc_counters': { 573 'forced_atoms_update_ids': { 574 '__idtype__': 1, 575 'kde': 1, 576 }, 577 }, 578 579 'system_settings_plugins_ids': { 580 'client_plugin': "client_plugin", 581 'server_plugin': "server_plugin", 582 'server_plugin_fatscope': "server_plugin_fatscope", 583 }, 584 585 'clientserverrepoid': "__system__", 586 'clientdbid': "client", 587 'serverdbid': "etpdb:", 588 'genericdbid': "generic", 589 'systemreleasefile': "/etc/sabayon-release", 590 591 # these are constants, for real settings 592 # look ad SystemSettings class 593 'socket_service': { # here are the constants 594 'hostname': "localhost", 595 'port': 1026, 596 'ssl_port': 1027, # above + 1 597 'timeout': 200, 598 'forked_requests_timeout': 300, 599 'max_command_length': 768000, # bytes 600 'threads': 5, 601 'session_ttl': 15, 602 'default_uid': 0, 603 'max_connections': 5, 604 'max_connections_per_host': 15, 605 'max_connections_per_host_barrier': 8, 606 'disabled_cmds': set(), 607 'ip_blacklist': set(), 608 'ssl_key': default_etp_confdir+"/socket_server.key", 609 'ssl_cert': default_etp_confdir+"/socket_server.crt", 610 'ssl_ca_cert': default_etp_confdir+"/socket_server.CA.crt", 611 'ssl_ca_pkey': default_etp_confdir+"/socket_server.CA.key", 612 'answers': { 613 'ok': chr(0)+"OK"+chr(0), # command run 614 'er': chr(0)+"ER"+chr(1), # execution error 615 'no': chr(0)+"NO"+chr(2), # not allowed 616 'cl': chr(0)+"CL"+chr(3), # close connection 617 'mcr': chr(0)+"MCR"+chr(4), # max connections reached 618 'eos': chr(0), # end of size, 619 'noop': chr(0)+"NOOP"+chr(0) 620 }, 621 }, 622 623 'install_sources': { 624 'unknown': 0, 625 'user': 1, 626 'automatic_dependency': 2, 627 }, 628 629 'ugc_doctypes': { 630 'comments': 1, 631 'bbcode_doc': 2, 632 'image': 3, 633 'generic_file': 4, 634 'youtube_video': 5, 635 }, 636 'ugc_doctypes_description': { 637 1: _('Comments'), 638 2: _('BBcode Documents'), 639 3: _('Images/Screenshots'), 640 4: _('Generic Files'), 641 5: _('YouTube(tm) Videos'), 642 }, 643 'ugc_doctypes_description_singular': { 644 1: _('Comment'), 645 2: _('BBcode Document'), 646 3: _('Image/Screenshot'), 647 4: _('Generic File'), 648 5: _('YouTube(tm) Video'), 649 }, 650 'ugc_accessfile': default_etp_ugc_confdir+"/access.xml", 651 'ugc_voterange': range(1, 6), 652 653 # handler settings 654 'handlers': { 655 # md5sum handler, 656 'md5sum': "md5sum.php?arch="+etpSys['arch']+"&package=", 657 }, 658 659 } 660 661 # set current nice level 662 try: 663 my_const['current_nice'] = os.nice(0) 664 except OSError: 665 pass 666 667 etpConst.update(my_const)
668
669 -def const_set_nice_level(nice_level = 0):
670 """ 671 Change current process scheduler "nice" level. 672 673 @param nice_level: new valid nice level 674 @type nice_level: int 675 @rtype: int 676 @return: current_nice new nice level 677 """ 678 default_nice = etpConst['default_nice'] 679 current_nice = etpConst['current_nice'] 680 delta = current_nice - default_nice 681 try: 682 etpConst['current_nice'] = os.nice(delta*-1+nice_level) 683 except OSError: 684 pass 685 return current_nice
686
687 -def const_extract_cli_repo_params(repostring, branch = None, product = None):
688 689 """ 690 Extract repository information from the provided repository string, 691 usually contained in the repository settings file, repositories.conf. 692 693 @param repostring: valid repository identifier 694 @type repostring: string 695 @rtype: tuple (string, dict) 696 @return: tuple composed by (repository identifier, extracted repository 697 metadata) 698 """ 699 700 if branch == None: 701 branch = etpConst['branch'] 702 if product == None: 703 product = etpConst['product'] 704 705 reponame = repostring.split("|")[1].strip() 706 repodesc = repostring.split("|")[2].strip() 707 repopackages = repostring.split("|")[3].strip() 708 repodatabase = repostring.split("|")[4].strip() 709 710 eapi3_port = int(etpConst['socket_service']['port']) 711 eapi3_ssl_port = int(etpConst['socket_service']['ssl_port']) 712 eapi3_formatcolon = repodatabase.rfind("#") 713 if eapi3_formatcolon != -1: 714 try: 715 ports = repodatabase[eapi3_formatcolon+1:].split(",") 716 eapi3_port = int(ports[0]) 717 if len(ports) > 1: 718 eapi3_ssl_port = int(ports[1]) 719 repodatabase = repodatabase[:eapi3_formatcolon] 720 except (ValueError, IndexError,): 721 eapi3_port = int(etpConst['socket_service']['port']) 722 eapi3_ssl_port = int(etpConst['socket_service']['ssl_port']) 723 724 dbformat = etpConst['etpdatabasefileformat'] 725 dbformatcolon = repodatabase.rfind("#") 726 if dbformatcolon != -1: 727 if dbformat in etpConst['etpdatabasesupportedcformats']: 728 try: 729 dbformat = repodatabase[dbformatcolon+1:] 730 except (IndexError, ValueError, TypeError,): 731 pass 732 repodatabase = repodatabase[:dbformatcolon] 733 734 mydata = {} 735 mydata['repoid'] = reponame 736 mydata['service_port'] = eapi3_port 737 mydata['ssl_service_port'] = eapi3_ssl_port 738 mydata['description'] = repodesc 739 mydata['packages'] = [] 740 mydata['plain_packages'] = [] 741 742 mydata['dbpath'] = etpConst['etpdatabaseclientdir'] + "/" + reponame + \ 743 "/" + product + "/" + etpConst['currentarch'] + "/" + branch 744 745 mydata['dbcformat'] = dbformat 746 if not dbformat in etpConst['etpdatabasesupportedcformats']: 747 mydata['dbcformat'] = etpConst['etpdatabasesupportedcformats'][0] 748 749 mydata['plain_database'] = repodatabase 750 751 mydata['database'] = repodatabase + "/" + product + "/" + \ 752 reponame + "/database/" + etpConst['currentarch'] + \ 753 "/" + branch 754 755 mydata['notice_board'] = mydata['database'] + "/" + \ 756 etpConst['rss-notice-board'] 757 758 mydata['local_notice_board'] = mydata['dbpath'] + "/" + \ 759 etpConst['rss-notice-board'] 760 761 mydata['dbrevision'] = "0" 762 dbrevision_file = os.path.join(mydata['dbpath'], 763 etpConst['etpdatabaserevisionfile']) 764 if os.path.isfile(dbrevision_file) and os.access(dbrevision_file, os.R_OK): 765 with open(dbrevision_file, "r") as dbrev_f: 766 mydata['dbrevision'] = dbrev_f.readline().strip() 767 768 769 # setup branch migration status file path 770 mydata['post_branch_hop_status_file'] = mydata['dbpath'] + "/" + \ 771 etpConst['etp_post_branch_hop_status_file'] 772 # setup branch upgrade status file path 773 mydata['post_branch_upgrade_status_file'] = mydata['dbpath'] + "/" + \ 774 etpConst['etp_post_branch_upgrade_status_file'] 775 776 # setup script paths 777 mydata['post_branch_hop_script'] = mydata['dbpath'] + "/" + \ 778 etpConst['etp_post_branch_hop_script'] 779 mydata['post_branch_upgrade_script'] = mydata['dbpath'] + "/" + \ 780 etpConst['etp_post_branch_upgrade_script'] 781 782 # initialize CONFIG_PROTECT 783 # will be filled the first time the db will be opened 784 mydata['configprotect'] = None 785 mydata['configprotectmask'] = None 786 repopackages = [x.strip() for x in repopackages.split() if x.strip()] 787 repopackages = [x for x in repopackages if (x.startswith('http://') or \ 788 x.startswith('ftp://') or x.startswith('file://'))] 789 790 for repo_package in repopackages: 791 try: 792 repo_package = str(repo_package) 793 except (UnicodeDecodeError,UnicodeEncodeError,): 794 continue 795 mydata['plain_packages'].append(repo_package) 796 mydata['packages'].append(repo_package + "/" + product + "/" + reponame) 797 798 return reponame, mydata
799
800 -def const_read_entropy_release():
801 """ 802 Read Entropy release file content and fill etpConst['entropyversion'] 803 804 @rtype: None 805 @return: None 806 """ 807 # handle Entropy Version 808 revision_file = "../libraries/revision" 809 if not os.path.isfile(revision_file): 810 revision_file = os.path.join(etpConst['installdir'], 811 'libraries/revision') 812 if os.path.isfile(revision_file) and \ 813 os.access(revision_file,os.R_OK): 814 815 with open(revision_file, "r") as rev_f: 816 myrev = rev_f.readline().strip() 817 etpConst['entropyversion'] = myrev
818 819
820 -def const_setup_entropy_pid(just_read = False):
821 822 """ 823 Setup Entropy pid file, if possible and if UID = 0 (root). 824 If the application is run with --no-pid-handling argument, 825 this function will have no effect. If just_read is specified, 826 this function will only try to read the current pid string in 827 the Entropy pid file (etpConst['pidfile']). If any other entropy 828 istance is currently owning the contained pid, etpConst['applicationlock'] 829 becomes True. 830 831 @param just_read: only read the current pid file, if any and if possible 832 @type just_read: bool 833 @rtype: None 834 @return: None 835 """ 836 837 if ("--no-pid-handling" in sys.argv) and (not just_read): 838 return 839 840 # PID creation 841 pid = os.getpid() 842 pid_file = etpConst['pidfile'] 843 if os.path.isfile(pid_file) and os.access(pid_file, os.R_OK): 844 845 try: 846 with open(pid_file,"r") as pid_f: 847 found_pid = str(pid_f.readline().strip()) 848 except (IOError, OSError, UnicodeEncodeError, UnicodeDecodeError,): 849 found_pid = "0000" # which is always invalid 850 851 if found_pid != str(pid): 852 # is found_pid still running ? 853 pid_path = "%s/proc/%s" % (etpConst['systemroot'], found_pid,) 854 if os.path.isdir(pid_path) and found_pid: 855 etpConst['applicationlock'] = True 856 elif not just_read: 857 # if root, write new pid 858 #if etpConst['uid'] == 0: 859 if os.access(pid_file, os.W_OK): 860 try: 861 with open(pid_file,"w") as pid_f: 862 pid_f.write(str(pid)) 863 pid_f.flush() 864 except IOError, err: 865 if err.errno == 30: # readonly filesystem 866 pass 867 else: 868 raise 869 try: 870 const_chmod_entropy_pid() 871 except OSError: 872 pass 873 874 elif not just_read: 875 876 #if etpConst['uid'] == 0: 877 if os.access(os.path.dirname(pid_file), os.W_OK): 878 879 if os.path.exists(pid_file): 880 if os.path.islink(pid_file): 881 os.remove(pid_file) 882 elif os.path.isdir(pid_file): 883 import shutil 884 shutil.rmtree(pid_file) 885 886 with open(pid_file,"w") as pid_fw: 887 pid_fw.write(str(pid)) 888 pid_fw.flush() 889 890 try: 891 const_chmod_entropy_pid() 892 except OSError: 893 pass
894
895 -def const_secure_config_file(config_file):
896 """ 897 Setup entropy file needing strict permissions, no world readable. 898 899 @param config_file: valid config file path 900 @type config_file: string 901 @rtype: None 902 @return: None 903 """ 904 try: 905 mygid = const_get_entropy_gid() 906 except KeyError: 907 mygid = 0 908 try: 909 const_setup_file(config_file, mygid, 0660) 910 except (OSError, IOError,): 911 pass
912
913 -def const_chmod_entropy_pid():
914 """ 915 Setup entropy pid file permissions, if possible. 916 917 @return: None 918 """ 919 try: 920 mygid = const_get_entropy_gid() 921 except KeyError: 922 mygid = 0 923 const_setup_file(etpConst['pidfile'], mygid, 0664)
924
925 -def const_create_working_dirs():
926 927 """ 928 Setup Entropy directory structure, as much automagically as possible. 929 930 @rtype: None 931 @return: None 932 """ 933 934 # handle pid file 935 piddir = os.path.dirname(etpConst['pidfile']) 936 if not os.path.exists(piddir) and (etpConst['uid'] == 0): 937 os.makedirs(piddir) 938 939 # create tmp dir 940 #if not os.path.isdir(xpakpath_dir): 941 # os.makedirs(xpakpath_dir,0775) 942 # const_setup_file(xpakpath_dir, 943 944 # create user if it doesn't exist 945 gid = None 946 try: 947 gid = const_get_entropy_gid() 948 except KeyError: 949 if etpConst['uid'] == 0: 950 # create group 951 # avoid checking cause it's not mandatory for entropy/equo itself 952 const_add_entropy_group() 953 try: 954 gid = const_get_entropy_gid() 955 except KeyError: 956 pass 957 958 # Create paths 959 keys = [x for x in etpConst if isinstance(etpConst[x], basestring)] 960 for key in keys: 961 962 if not etpConst[key] or \ 963 etpConst[key].endswith(".conf") or \ 964 not os.path.isabs(etpConst[key]) or \ 965 etpConst[key].endswith(".cfg") or \ 966 etpConst[key].endswith(".tmp") or \ 967 etpConst[key].find(".db") != -1 or \ 968 etpConst[key].find(".log") != -1 or \ 969 os.path.isdir(etpConst[key]) or \ 970 not key.endswith("dir"): 971 continue 972 973 # allow users to create dirs in custom paths, 974 # so don't fail here even if we don't have permissions 975 try: 976 key_dir = etpConst[key] 977 d_paths = [] 978 while not os.path.isdir(key_dir): 979 d_paths.append(key_dir) 980 key_dir = os.path.dirname(key_dir) 981 d_paths = sorted(d_paths) 982 for d_path in d_paths: 983 os.mkdir(d_path) 984 const_setup_file(d_path, gid, 0775) 985 except (OSError, IOError,): 986 pass 987 988 if gid: 989 etpConst['entropygid'] = gid 990 if not os.path.isdir(etpConst['entropyworkdir']): 991 try: 992 os.makedirs(etpConst['entropyworkdir']) 993 except OSError: 994 pass 995 w_gid = os.stat(etpConst['entropyworkdir'])[stat.ST_GID] 996 if w_gid != gid: 997 const_setup_perms(etpConst['entropyworkdir'], gid) 998 999 if not os.path.isdir(etpConst['entropyunpackdir']): 1000 try: 1001 os.makedirs(etpConst['entropyunpackdir']) 1002 except OSError: 1003 pass 1004 try: 1005 w_gid = os.stat(etpConst['entropyunpackdir'])[stat.ST_GID] 1006 if w_gid != gid: 1007 if os.path.isdir(etpConst['entropyunpackdir']): 1008 const_setup_perms(etpConst['entropyunpackdir'], gid) 1009 except OSError: 1010 pass 1011 # always setup /var/lib/entropy/client permissions 1012 if not const_islive(): 1013 # aufs/unionfs will start to leak otherwise 1014 const_setup_perms(etpConst['etpdatabaseclientdir'], gid)
1015
1016 -def const_configure_lock_paths():
1017 """ 1018 Setup Entropy lock file paths. 1019 1020 @rtype: None 1021 @return: None 1022 """ 1023 etpConst['locks'] = { 1024 'using_resources': os.path.join(etpConst['etpdatabaseclientdir'], 1025 '.using_resources'), 1026 }
1027 1028
1029 -def const_extract_srv_repo_params(repostring, product = None):
1030 """ 1031 Analyze a server repository string (usually contained in server.conf), 1032 extracting all the parameters. 1033 1034 @param repostring: repository string 1035 @type repostring: string 1036 @keyword product: system product which repository belongs to 1037 @rtype: None 1038 @return: None 1039 """ 1040 1041 if product == None: 1042 product = etpConst['product'] 1043 1044 mydata = {} 1045 repoid = repostring.split("|")[1].strip() 1046 repodesc = repostring.split("|")[2].strip() 1047 repouris = repostring.split("|")[3].strip() 1048 repohandlers = repostring.split("|")[4].strip() 1049 1050 service_url = None 1051 eapi3_port = int(etpConst['socket_service']['port']) 1052 eapi3_ssl_port = int(etpConst['socket_service']['ssl_port']) 1053 if len(repostring.split("|")) > 5: 1054 service_url = repostring.split("|")[5].strip() 1055 1056 eapi3_formatcolon = service_url.rfind("#") 1057 if eapi3_formatcolon != -1: 1058 try: 1059 ports = service_url[eapi3_formatcolon+1:].split(",") 1060 eapi3_port = int(ports[0]) 1061 if len(ports) > 1: 1062 eapi3_ssl_port = int(ports[1]) 1063 service_url = service_url[:eapi3_formatcolon] 1064 except (ValueError, IndexError,): 1065 eapi3_port = int(etpConst['socket_service']['port']) 1066 eapi3_ssl_port = int(etpConst['socket_service']['ssl_port']) 1067 1068 mydata = {} 1069 mydata['repoid'] = repoid 1070 mydata['description'] = repodesc 1071 mydata['mirrors'] = [] 1072 mydata['community'] = False 1073 mydata['service_url'] = service_url 1074 mydata['service_port'] = eapi3_port 1075 mydata['ssl_service_port'] = eapi3_ssl_port 1076 if repohandlers: 1077 repohandlers = os.path.join(repohandlers, product, repoid, "handlers") 1078 mydata['handler'] = repohandlers 1079 uris = repouris.split() 1080 for uri in uris: 1081 mydata['mirrors'].append(uri) 1082 1083 return repoid, mydata
1084
1085 -def const_setup_perms(mydir, gid):
1086 """ 1087 Setup permissions and group id (GID) to a directory, recursively. 1088 1089 @param mydir: valid file path 1090 @type mydir: string 1091 @param gid: valid group id (GID) 1092 @type gid: int 1093 @rtype: None 1094 @return: None 1095 """ 1096 if gid == None: 1097 return 1098 for currentdir, subdirs, files in os.walk(mydir): 1099 try: 1100 cur_gid = os.stat(currentdir)[stat.ST_GID] 1101 if cur_gid != gid: 1102 os.chown(currentdir, -1, gid) 1103 cur_mod = const_get_chmod(currentdir) 1104 if cur_mod != oct(0775): 1105 os.chmod(currentdir, 0775) 1106 except OSError: 1107 pass 1108 for item in files: 1109 item = os.path.join(currentdir, item) 1110 try: 1111 const_setup_file(item, gid, 0664) 1112 except OSError: 1113 pass
1114
1115 -def const_setup_file(myfile, gid, chmod):
1116 """ 1117 Setup file permissions and group id (GID). 1118 1119 @param myfile: valid file path 1120 @type myfile: string 1121 @param gid: valid group id (GID) 1122 @type gid: int 1123 @param chmod: permissions 1124 @type chmod: integer representing an octal 1125 @rtype: None 1126 @return: None 1127 """ 1128 cur_gid = os.stat(myfile)[stat.ST_GID] 1129 if cur_gid != gid: 1130 os.chown(myfile, -1, gid) 1131 const_set_chmod(myfile, chmod)
1132 1133 # you need to convert to int
1134 -def const_get_chmod(myfile):
1135 """ 1136 This function get the current permissions of the specified 1137 file. If you want to use the returning value with const_set_chmod 1138 you need to convert it back to int. 1139 1140 @param myfile: valid file path 1141 @type myfile: string 1142 @rtype: integer(8) (octal) 1143 @return: octal representing permissions 1144 """ 1145 myst = os.stat(myfile)[stat.ST_MODE] 1146 return oct(myst & 0777)
1147
1148 -def const_set_chmod(myfile, chmod):
1149 """ 1150 This function sets specified permissions to a file. 1151 If they differ from the current ones. 1152 1153 @param myfile: valid file path 1154 @type myfile: string 1155 @param chmod: permissions 1156 @type chmod: integer representing an octal 1157 @rtype: None 1158 @return: None 1159 """ 1160 cur_mod = const_get_chmod(myfile) 1161 if cur_mod != oct(chmod): 1162 os.chmod(myfile, chmod)
1163
1164 -def const_get_entropy_gid():
1165 """ 1166 This function tries to retrieve the "entropy" user group 1167 GID. 1168 1169 @rtype: None 1170 @return: None 1171 @raise KeyError: when "entropy" system GID is not available 1172 """ 1173 group_file = etpConst['systemroot']+'/etc/group' 1174 if not os.path.isfile(group_file): 1175 raise KeyError 1176 1177 with open(group_file,"r") as group_f: 1178 for line in group_f.readlines(): 1179 if line.startswith('%s:' % (etpConst['sysgroup'],)): 1180 try: 1181 gid = int(line.split(":")[2]) 1182 except ValueError: 1183 raise KeyError 1184 return gid 1185 raise KeyError
1186
1187 -def const_add_entropy_group():
1188 """ 1189 This function looks for an "entropy" user group. 1190 If not available, it tries to create one. 1191 1192 @rtype: None 1193 @return: None 1194 @raise KeyError: if ${ROOT}/etc/group is not found 1195 """ 1196 group_file = etpConst['systemroot']+'/etc/group' 1197 if not os.path.isfile(group_file): 1198 raise KeyError 1199 ids = set() 1200 1201 with open(group_file,"r") as group_f: 1202 for line in group_f.readlines(): 1203 if line and line.split(":"): 1204 try: 1205 myid = int(line.split(":")[2]) 1206 except ValueError: 1207 pass 1208 ids.add(myid) 1209 if ids: 1210 # starting from 1000, get the first free 1211 new_id = 1000 1212 while 1: 1213 new_id += 1 1214 if new_id not in ids: 1215 break 1216 else: 1217 new_id = 10000 1218 1219 with open(group_file,"aw") as group_fw: 1220 group_fw.seek(0, 2) 1221 app_line = "entropy:x:%s:\n" % (new_id,) 1222 group_fw.write(app_line) 1223 group_fw.flush()
1224
1225 -def const_islive():
1226 """ 1227 Live environments (Operating System running off a CD/DVD) 1228 must feature the "cdroot" parameter in kernel /proc/cmdline 1229 1230 Sample code: 1231 >>> from entropy.const import const_islive 1232 >>> const_islive() 1233 False 1234 1235 @rtype: bool 1236 @return: determine wether this is a Live system or not 1237 """ 1238 if "cdroot" in etpConst['cmdline']: 1239 return True 1240 return False
1241
1242 -def const_kill_threads():
1243 """ 1244 Entropy threads killer. Even if Python threads cannot 1245 be stopped or killed, TimeScheduled ones can, exporting 1246 the kill() method. 1247 1248 Sample code: 1249 >>> from entropy.const import const_kill_threads 1250 >>> const_kill_threads() 1251 1252 @rtype: None 1253 @return: None 1254 """ 1255 import threading 1256 threads = threading.enumerate() 1257 for running_t in threads: 1258 if not hasattr(running_t,'kill'): 1259 continue 1260 running_t.kill() 1261 running_t.join()
1262
1263 -def __const_handle_exception(etype, value, t_back):
1264 """ 1265 Our default Python exception handler. It kills 1266 all the threads generated by Entropy before 1267 raising exceptions. Overloads sys.excepthook, 1268 internal function !! 1269 1270 @param etype: exception type 1271 @type etype: exception type 1272 @param value: exception data 1273 @type value: string 1274 @param t_back: traceback object? 1275 @type t_back: Python traceback object 1276 @rtype: default Python exceptions hook 1277 @return: sys.__excepthook__ 1278 """ 1279 try: 1280 const_kill_threads() 1281 except ImportError: 1282 pass 1283 return sys.__excepthook__(etype, value, t_back)
1284
1285 -def const_debug_write(identifier, msg):
1286 """ 1287 Entropy debugging output write functions. 1288 1289 @param identifier: debug identifier 1290 @type identifier: string 1291 @param msg: debugging message 1292 @type msg: string 1293 @rtype: None 1294 @return: None 1295 """ 1296 if etpUi['debug']: 1297 sys.stdout.write("%s: %s" % (identifier, msg + "\n"))
1298 1299 # load config 1300 initconfig_entropy_constants(etpSys['rootdir']) 1301