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