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