Package entropy :: Module const

Source Code for Module entropy.const

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