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