#!/usr/bin/python ''' # DESCRIPTION: # Variables container Copyright (C) 2007-2008 Fabio Erculiani This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA ''' import random import sys import os import stat import exceptionTools from entropy_i18n import _ # Specifications of the content of packages metadata ''' data = { 'name': u"", # the Package Name 'version': u"", # the Package version 'description': u"", # the Package description 'category': u"", # the gentoo category 'chost': u"", # the CHOST used to compile it 'cflags': u"", # CFLAGS used 'cxxflags': u"", # CXXFLAGS used 'homepage': u"", # home page of the package 'useflags': u"", # USE flags used 'license': u"", # License adpoted 'keywords': u"", # supported ARCHs (by the SRC) 'branch': u"", # package branch location 'download': u"", # link to download the binary package 'digest': u"", # md5 hash of the .tbz2 package 'sources': u"", # link to the sources 'slot': u"", # this is filled if the package is slotted 'content': u"", # content of the package (files) 'mirrorlinks': u"", # =mirror://openoffice|link1|link2|link3 'dependencies': u"", # dependencies 'conflicts': u"", # blockers 'etpapi': u"", # Entropy API revision 'datecreation': u"", # mtime of the .tbz2 file 'size': u"", # the package size 'versiontag': u"", # particular version tag 'provide': u"", # like, cups provides dep virtual/lpr 'systempackage': u"", # if this is a system package, this will be != "" 'config_protect': u"", # list of directories that contain files that should not be overwritten 'config_protect_mask': u"", # list of directories that contain files that should be overwritten 'disksize': u"", # size on the hard disk in bytes (integer) 'counter': u"", # aka. COUNTER file 'messages': u"", # elog content from portage 'eclasses': u"", # eclasses used by the ebuild 'needed': set, # runtime libraries needed by the package 'trigger': bool, # this will become a bool, containing info about external trigger presence 'injected': bool, # if the package has been injected manually, this will be true 'licensedata': dict # dictionary that contains license text } ''' # Entropy SQL initialization Schema and data structure etpSQLInitDestroyAll = """ DROP TABLE IF EXISTS baseinfo; DROP TABLE IF EXISTS extrainfo; DROP TABLE IF EXISTS content; DROP TABLE IF EXISTS contentreference; DROP TABLE IF EXISTS contenttypes; DROP TABLE IF EXISTS dependencies; DROP TABLE IF EXISTS dependenciesreference; DROP TABLE IF EXISTS provide; DROP TABLE IF EXISTS conflicts; DROP TABLE IF EXISTS neededlibs; DROP TABLE IF EXISTS libraries; DROP TABLE IF EXISTS mirrorlinks; DROP TABLE IF EXISTS sources; DROP TABLE IF EXISTS sourcesreference; DROP TABLE IF EXISTS useflags; DROP TABLE IF EXISTS useflagsreference; DROP TABLE IF EXISTS keywords; DROP TABLE IF EXISTS binkeywords; DROP TABLE IF EXISTS keywordsreference; DROP TABLE IF EXISTS categories; DROP TABLE IF EXISTS licenses; DROP TABLE IF EXISTS flags; DROP TABLE IF EXISTS systempackages; DROP TABLE IF EXISTS configprotect; DROP TABLE IF EXISTS configprotectmask; DROP TABLE IF EXISTS configprotectreference; DROP TABLE IF EXISTS installedtable; DROP TABLE IF EXISTS dependstable; DROP TABLE IF EXISTS sizes; DROP TABLE IF EXISTS messages; DROP TABLE IF EXISTS counters; DROP TABLE IF EXISTS eclasses; DROP TABLE IF EXISTS eclassesreference; DROP TABLE IF EXISTS needed; DROP TABLE IF EXISTS neededreference; DROP TABLE IF EXISTS triggers; DROP TABLE IF EXISTS countersdata; DROP TABLE IF EXISTS injected; DROP TABLE IF EXISTS treeupdates; DROP TABLE IF EXISTS treeupdatesactions; DROP TABLE IF EXISTS library_breakages; DROP TABLE IF EXISTS licensedata; DROP TABLE IF EXISTS licenses_accepted; DROP TABLE IF EXISTS trashedcounters; DROP TABLE IF EXISTS entropy_misc_counters; DROP TABLE IF EXISTS categoriesdescription; """ etpSQLInit = """ CREATE TABLE baseinfo ( idpackage INTEGER PRIMARY KEY AUTOINCREMENT, atom VARCHAR, idcategory INTEGER, name VARCHAR, version VARCHAR, versiontag VARCHAR, revision INTEGER, branch VARCHAR, slot VARCHAR, idlicense INTEGER, etpapi INTEGER, trigger INTEGER ); CREATE TABLE extrainfo ( idpackage INTEGER PRIMARY KEY, description VARCHAR, homepage VARCHAR, download VARCHAR, size VARCHAR, idflags INTEGER, digest VARCHAR, datecreation VARCHAR ); CREATE TABLE content ( idpackage INTEGER, file VARCHAR, type VARCHAR ); CREATE TABLE provide ( idpackage INTEGER, atom VARCHAR ); CREATE TABLE dependencies ( idpackage INTEGER, iddependency INTEGER, type INTEGER ); CREATE TABLE dependenciesreference ( iddependency INTEGER PRIMARY KEY AUTOINCREMENT, dependency VARCHAR ); CREATE TABLE conflicts ( idpackage INTEGER, conflict VARCHAR ); CREATE TABLE mirrorlinks ( mirrorname VARCHAR, mirrorlink VARCHAR ); CREATE TABLE sources ( idpackage INTEGER, idsource INTEGER ); CREATE TABLE sourcesreference ( idsource INTEGER PRIMARY KEY AUTOINCREMENT, source VARCHAR ); CREATE TABLE useflags ( idpackage INTEGER, idflag INTEGER ); CREATE TABLE useflagsreference ( idflag INTEGER PRIMARY KEY AUTOINCREMENT, flagname VARCHAR ); CREATE TABLE keywords ( idpackage INTEGER, idkeyword INTEGER ); CREATE TABLE keywordsreference ( idkeyword INTEGER PRIMARY KEY AUTOINCREMENT, keywordname VARCHAR ); CREATE TABLE categories ( idcategory INTEGER PRIMARY KEY AUTOINCREMENT, category VARCHAR ); CREATE TABLE licenses ( idlicense INTEGER PRIMARY KEY AUTOINCREMENT, license VARCHAR ); CREATE TABLE flags ( idflags INTEGER PRIMARY KEY AUTOINCREMENT, chost VARCHAR, cflags VARCHAR, cxxflags VARCHAR ); CREATE TABLE configprotect ( idpackage INTEGER PRIMARY KEY, idprotect INTEGER ); CREATE TABLE configprotectmask ( idpackage INTEGER PRIMARY KEY, idprotect INTEGER ); CREATE TABLE configprotectreference ( idprotect INTEGER PRIMARY KEY AUTOINCREMENT, protect VARCHAR ); CREATE TABLE systempackages ( idpackage INTEGER PRIMARY KEY ); CREATE TABLE injected ( idpackage INTEGER PRIMARY KEY ); CREATE TABLE installedtable ( idpackage INTEGER PRIMARY KEY, repositoryname VARCHAR ); CREATE TABLE sizes ( idpackage INTEGER PRIMARY KEY, size INTEGER ); CREATE TABLE messages ( idpackage INTEGER, message VARCHAR ); CREATE TABLE counters ( counter INTEGER, idpackage INTEGER PRIMARY KEY, branch VARCHAR ); CREATE TABLE trashedcounters ( counter INTEGER ); CREATE TABLE eclasses ( idpackage INTEGER, idclass INTEGER ); CREATE TABLE eclassesreference ( idclass INTEGER PRIMARY KEY AUTOINCREMENT, classname VARCHAR ); CREATE TABLE needed ( idpackage INTEGER, idneeded INTEGER, elfclass INTEGER ); CREATE TABLE neededreference ( idneeded INTEGER PRIMARY KEY AUTOINCREMENT, library VARCHAR ); CREATE TABLE treeupdates ( repository VARCHAR PRIMARY KEY, digest VARCHAR ); CREATE TABLE treeupdatesactions ( idupdate INTEGER PRIMARY KEY AUTOINCREMENT, repository VARCHAR, command VARCHAR, branch VARCHAR, date VARCHAR ); CREATE TABLE binkeywords ( idpackage INTEGER, idkeyword INTEGER ); CREATE TABLE licensedata ( licensename VARCHAR UNIQUE, text BLOB, compressed INTEGER ); CREATE TABLE licenses_accepted ( licensename VARCHAR UNIQUE ); CREATE TABLE triggers ( idpackage INTEGER PRIMARY KEY, data BLOB ); CREATE TABLE entropy_misc_counters ( idtype INTEGER PRIMARY KEY, counter INTEGER ); CREATE TABLE categoriesdescription ( category VARCHAR, locale VARCHAR, description VARCHAR ); """ # ETP_ARCH_CONST setup if os.uname()[4] == "x86_64": ETP_ARCH_CONST = "amd64" else: ETP_ARCH_CONST = "x86" etpSys = { 'archs': ["x86", "amd64"], 'api': '3', 'arch': ETP_ARCH_CONST, 'rootdir': "", 'maxthreads': 100, 'dirstoclean': set(), 'serverside': False, 'killpids': set() } etpUi = { 'debug': False, 'quiet': False, 'verbose': False, 'ask': False, 'pretend': False, 'mute': False, 'nolog': False, 'clean': False, 'postinstall_triggers_disable': set(), 'postremove_triggers_disable': set(), 'preinstall_triggers_disable': set(), 'preremove_triggers_disable': set() } if "--debug" in sys.argv: etpUi['debug'] = True # static logging stuff ETP_LOGLEVEL_NORMAL = 1 ETP_LOGLEVEL_VERBOSE = 2 ETP_LOGPRI_INFO = "[ INFO ]" ETP_LOGPRI_WARNING = "[ WARNING ]" ETP_LOGPRI_ERROR = "[ ERROR ]" # disk caching dictionary etpCache = { 'configfiles': 'conf/scanfs', # used to store information about files that should be merged using "equo conf merge" 'dbMatch': 'match/db', # db atom match cache 'dbSearch': 'search/db', # db search cache 'atomMatch': 'atom_match/atom_match_', # used to store info about repository dependencies solving 'install': 'resume/resume_install', # resume cache (install) 'remove': 'resume/resume_remove', # resume cache (remove) 'world': 'resume/resume_world', # resume cache (world) 'world_update': 'world_update/world_cache_', 'world_available': 'world_available/available_cache_', 'check_package_update': 'check_update/package_update_', 'advisories': 'security/advisories_cache_', 'dep_tree': 'deptree/dep_tree_', 'depends_tree': 'depends/depends_tree_', 'filter_satisfied_deps': 'depfilter/filter_satisfied_deps_', 'library_breakage': 'libs_break/library_breakage_', 'repolist': 'repos/repolist', 'repository_server': 'reposerver/item', 'eapi3_fetch': 'eapi3/segment_', } # ahahaha etpExitMessages = { 0: _("You should run equo --help"), 1: _("You didn't run equo --help, did you?"), 2: _("Did you even read equo --help??"), 3: _("I give up. Run that equo --help !!!!!!!"), 4: _("OH MY GOD. RUN equo --heeeeeeeeeeeeeelp"), 5: _("Illiteracy is a huge problem in this world"), 6: _("Ok i give up, you are hopeless"), 7: _("Go to hell."), } # information about what has been done on the database, # those dicts will be dumped to a file and used by activator to update and upload .rss etpRSSMessages = { 'added': {}, # packages that has been added 'removed': {}, # packages that has been removed 'commitmessage': "", # commit message from the guy who is going to submit a repository update 'light': {} # this stuff will be pushed to the light rss } # CACHING dictionaries idpackageValidatorCache = {} maskingReasonsStorage = {} linkerPaths = [] # repository atoms updates digest cache repositoryUpdatesDigestCache_disk = {} fetch_repository_if_not_available_cache = {} repo_error_messages_cache = set() ### Application disk cache def const_resetCache(): idpackageValidatorCache.clear() del linkerPaths[:] repositoryUpdatesDigestCache_disk.clear() fetch_repository_if_not_available_cache.clear() repo_error_messages_cache.clear() maskingReasonsStorage.clear() # Client packages/database repositories etpRepositories = {} etpRepositoriesExcluded = {} etpRepositoriesOrder = [] # remote section etpRemoteFailures = {} # dict of excluded mirrors due to failures, # it contains mirror name and failure count | > 5 == ignore mirror # your bible etpConst = {} # database status dict etpDbStatus = {} # =============================================================================================== # BEGINNING OF THE DYNAMIC SECTION # =============================================================================================== def initConfig_entropyConstants(rootdir): if rootdir and not os.path.isdir(rootdir): raise exceptionTools.FileNotFound("FileNotFound: not a valid chroot.") # save backed up settings if etpConst.has_key('backed_up'): backed_up_settings = etpConst.pop('backed_up') else: backed_up_settings = {} const_resetCache() const_defaultSettings(rootdir) const_readEntropyRelease() const_createWorkingDirectories() const_setupEntropyPid() const_readEntropySettings() const_readRepositoriesSettings() const_readSocketSettings() const_configureLockPaths() initConfig_clientConstants() # server stuff const_readReagentSettings() const_readServerSettings() const_readActivatorSettings() # reflow back settings etpConst.update(backed_up_settings) etpConst['backed_up'] = backed_up_settings.copy() const_setupWithEnvironment() def initConfig_clientConstants(): const_readEquoSettings() def const_defaultSettings(rootdir): ETP_DIR = rootdir+"/var/lib/entropy" ETP_TMPDIR = "/tmp" ETP_RANDOM = str(random.random())[2:7] ETP_TMPFILE = "/.random-"+ETP_RANDOM+".tmp" ETP_REPODIR = "/packages/"+ETP_ARCH_CONST ETP_PORTDIR = rootdir+"/usr/portage" ETP_DISTFILESDIR = "/distfiles" ETP_DBDIR = "/database/"+ETP_ARCH_CONST ETP_DBFILE = "packages.db" ETP_DBCLIENTFILE = "equo.db" ETP_CLIENT_REPO_DIR = "/client" ETP_TRIGGERSDIR = "/triggers/"+ETP_ARCH_CONST ETP_SMARTAPPSDIR = "/smartapps/"+ETP_ARCH_CONST ETP_SMARTPACKAGESDIR = "/smartpackages/"+ETP_ARCH_CONST ETP_CACHESDIR = "/caches/" ETP_SECURITYDIR = "/glsa/" ETP_LOG_DIR = ETP_DIR+"/"+"logs" ETP_CONF_DIR = rootdir+"/etc/entropy" ETP_SYSLOG_DIR = rootdir+"/var/log/entropy/" ETP_VAR_DIR = rootdir+"/var/tmp/entropy" edbCOUNTER = rootdir+"/var/cache/edb/counter" etpConst.clear() myConst = { 'server_repositories': {}, 'community': { 'mode': False, }, 'backed_up': {}, 'sql_destroy': etpSQLInitDestroyAll, 'sql_init': etpSQLInit, 'installdir': '/usr/lib/entropy', # entropy default installation directory 'packagestmpdir': ETP_DIR+ETP_TMPDIR, # etpConst['packagestmpdir'] --> temp directory 'packagestmpfile': ETP_DIR+ETP_TMPDIR+ETP_TMPFILE, # etpConst['packagestmpfile'] --> general purpose tmp file 'packagesbindir': ETP_DIR+ETP_REPODIR, # etpConst['packagesbindir'] --> repository where the packages will be stored # by the clients: to query if a package has been already downloaded # by the servers or rsync mirrors: to store already uploaded packages to the main rsync server 'smartappsdir': ETP_DIR+ETP_SMARTAPPSDIR, # etpConst['smartappsdir'] location where smart apps files are places 'smartpackagesdir': ETP_DIR+ETP_SMARTPACKAGESDIR, # etpConst['smartpackagesdir'] location where smart packages files are places 'triggersdir': ETP_DIR+ETP_TRIGGERSDIR, # etpConst['triggersdir'] location where external triggers are placed 'portagetreedir': ETP_PORTDIR, # directory where is stored our local portage tree 'distfilesdir': ETP_PORTDIR+ETP_DISTFILESDIR, # directory where our sources are downloaded 'confdir': ETP_CONF_DIR, # directory where entropy stores its configuration 'entropyconf': ETP_CONF_DIR+"/entropy.conf", # entropy.conf file 'repositoriesconf': ETP_CONF_DIR+"/repositories.conf", # repositories.conf file 'activatorconf': ETP_CONF_DIR+"/activator.conf", # activator.conf file 'serverconf': ETP_CONF_DIR+"/server.conf", # server.conf file (generic server side settings) 'reagentconf': ETP_CONF_DIR+"/reagent.conf", # reagent.conf file 'equoconf': ETP_CONF_DIR+"/equo.conf", # equo.conf file 'socketconf': ETP_CONF_DIR+"/socket.conf", # socket.conf file 'packagesrelativepath': "packages/"+ETP_ARCH_CONST+"/", # user by client interfaces 'entropyworkdir': ETP_DIR, # Entropy workdir 'entropyunpackdir': ETP_VAR_DIR, # Entropy unpack directory 'entropyimagerelativepath': "image", # Entropy packages image directory 'entropyxpakrelativepath': "xpak", # Gentoo xpak temp directory path 'entropyxpakdatarelativepath': "data", # Gentoo xpak metadata directory path 'entropyxpakfilename': "metadata.xpak", # Gentoo xpak metadata file name 'etpdatabasemaskfile': ETP_DBFILE+".mask", # the local/remote database revision file 'etpdatabaseupdatefile': ETP_DBFILE+".repo_updates", # the local/remote database revision file 'etpdatabaselicwhitelistfile': ETP_DBFILE+".lic_whitelist", # the local/remote database revision file 'etpdatabaserevisionfile': ETP_DBFILE+".revision", # the local/remote database revision file 'etpdatabasehashfile': ETP_DBFILE+".md5", # its checksum 'etpdatabasedumphashfilebz2': ETP_DBFILE+".dump.bz2.md5", 'etpdatabasedumphashfilegzip': ETP_DBFILE+".dump.gz.md5", 'etpdatabaselockfile': ETP_DBFILE+".lock", # the remote database lock file 'etpdatabaseeapi3lockfile': ETP_DBFILE+".eapi3_lock", # the remote database lock file 'etpdatabasedownloadlockfile': ETP_DBFILE+".download.lock", # the remote database download lock file 'etpdatabasetaintfile': ETP_DBFILE+".tainted", # when this file exists, the database is not synced anymore with the online one 'etpdatabasefile': ETP_DBFILE, # Entropy sqlite database file ETP_DIR+ETP_DBDIR+"/packages.db" 'etpdatabasefilegzip': ETP_DBFILE+".gz", # Entropy sqlite database file (gzipped) 'etpdatabasefilebzip2': ETP_DBFILE+".bz2", # Entropy sqlite database file (bzipped2) 'etpdatabasedumpbzip2': ETP_DBFILE+".dump.bz2", # Entropy sqlite database dump file (bzipped2) 'etpdatabasedumpgzip': ETP_DBFILE+".dump.gz", # Entropy sqlite database dump file (gzipped) 'etpdatabasedump': ETP_DBFILE+".dump", # Entropy sqlite database dump file 'etpdatabasefileformat': "bz2", # Entropy default compressed database format 'etpdatabasesupportedcformats': ["bz2","gz"], # Entropy compressed databases format support 'etpdatabasecompressclasses': { "bz2": ("bz2.BZ2File","unpackBzip2","etpdatabasefilebzip2","etpdatabasedumpbzip2","etpdatabasedumphashfilebz2"), "gz": ("gzip.GzipFile","unpackGzip","etpdatabasefilegzip","etpdatabasedumpgzip","etpdatabasedumphashfilegzip") }, 'rss-feed': True, # enable/disable packages RSS feed feature 'rss-name': "packages.rss", # default name of the RSS feed 'rss-light-name': "updates.rss", # light version 'rss-base-url': "http://packages.sabayonlinux.org/", # default URL to the entropy web interface (overridden in reagent.conf) 'rss-website-url': "http://www.sabayonlinux.org/", # default URL to the Operating System website (overridden in reagent.conf) 'rss-dump-name': "rss_database_actions", # xml file where will be dumped etpRSSMessages dictionary 'rss-max-entries': 10000, # maximum rss entries 'rss-light-max-entries': 300, # max entries for the light version 'rss-managing-editor': "lxnay@sabayonlinux.org", # updates submitter 'packagesext': ".tbz2", 'packageshashfileext': ".md5", # Extension of the file that contains the checksum of its releated package file 'packagesexpirationfileext': ".expired", # Extension of the file that "contains" expiration mtime 'packagesexpirationdays': 15, # number of days after a package will be removed from mirrors 'triggername': "trigger", # name of the trigger file that would be executed by equo inside triggerTools 'proxy': { 'ftp': None, 'http': None, 'username': None, 'password': None }, # proxy configuration information, used system wide 'entropyloglevel': 1, # # Entropy log level (default: 1 - see entropy.conf for more info) 'socketloglevel': 2, # # Entropy Socket Interface log level 'enzymeloglevel': 2, # # Entropy Socket Interface log level 'equologlevel': 1, # # Equo log level (default: 1 - see equo.conf for more info) 'logdir': ETP_LOG_DIR , # Log dir where ebuilds store their stuff 'syslogdir': ETP_SYSLOG_DIR, # Entropy system tools log directory 'entropylogfile': ETP_SYSLOG_DIR+"entropy.log", # Activator operations log file 'equologfile': ETP_SYSLOG_DIR+"equo.log", # Activator operations log file 'socketlogfile': ETP_SYSLOG_DIR+"socket.log", # Activator operations log file 'enzymelogfile': ETP_SYSLOG_DIR+"enzyme.log", # Activator operations log file 'etpdatabaseclientdir': ETP_DIR+ETP_CLIENT_REPO_DIR+ETP_DBDIR, 'etpdatabaseclientfilepath': ETP_DIR+ETP_CLIENT_REPO_DIR+ETP_DBDIR+"/"+ETP_DBCLIENTFILE, # path to equo.db - client side database file 'dbnamerepoprefix': "repo_", # prefix of the name of self.dbname in EntropyDatabaseInterface class for the repositories 'etpapi': etpSys['api'], # Entropy database API revision 'currentarch': etpSys['arch'], # contains the current running architecture 'supportedarchs': etpSys['archs'], # Entropy supported Archs 'branches': [], # available branches, this only exists for the server part, these settings will be overridden by server.conf ones 'branch': "3.5", # default choosen branch (overridden by setting in repositories.conf) 'keywords': set([etpSys['arch'],"~"+etpSys['arch']]), # default allowed package keywords 'gentoo-compat': False, # Gentoo compatibility (/var/db/pkg + Portage availability) 'edbcounter': edbCOUNTER, 'filesystemdirs': ['/bin','/emul','/etc','/lib','/lib32','/lib64','/opt','/sbin','/usr','/var'], # directory of the filesystem 'filesystemdirsmask': [ '/var/cache','/var/db','/var/empty','/var/log','/var/mail','/var/tmp','/var/www', '/usr/portage', '/usr/src', '/etc/skel', '/etc/ssh', '/etc/ssl', '/var/run', '/var/spool/cron', '/var/lib/init.d', '/lib/modules', '/etc/env.d', '/etc/gconf', '/etc/runlevels', '/lib/splash/cache', '/usr/share/mime', '/etc/portage', '/var/spool', '/var/lib', '/usr/lib/locale','/lib64/splash/cache' ], 'libtest_blacklist': [ 'www-client/mozilla-firefox-bin', 'dev-java/blackdown-jdk', ], 'libtest_files_blacklist': [ '/usr/lib64/openmotif-2.2/libMrm.so.3', '/usr/lib64/openmotif-2.2/libXm.so.3', '/usr/lib/openmotif-2.2/libMrm.so.3', '/usr/lib/openmotif-2.2/libXm.so.3' ], 'officialserverrepositoryid': "sabayonlinux.org", # our official repository name 'officialrepositoryid': "sabayonlinux.org", # our official repository name 'conntestlink': "http://www.google.com", 'databasestarttag': "|ENTROPY:PROJECT:DB:MAGIC:START|", # tag to append to .tbz2 file before entropy database (must be 32bytes) 'pidfile': ETP_DIR+"/entropy.pid", 'applicationlock': False, 'filesbackup': True, # option to keep a backup of config files after being overwritten by equo conf update 'collisionprotect': 1, # collision protection option, read equo.conf for more info 'configprotect': [], # list of user specified CONFIG_PROTECT directories (see Gentoo manual to understand the meaining of this parameter) 'configprotectmask': [], # list of user specified CONFIG_PROTECT_MASK directories 'configprotectskip': [], # list of user specified configuration files that should be ignored and kept as they are 'dbconfigprotect': [], # installed database CONFIG_PROTECT directories 'dbconfigprotectmask': [], # installed database CONFIG_PROTECT_MASK directories 'configprotectcounter': 0, # this will be used to show the number of updated files at the end of the processes 'entropyversion': "1.0", # default Entropy release version 'systemname': "Sabayon Linux", # default system name (overidden by entropy.conf settings) 'product': "standard", # Product identificator (standard, professional...) 'errorstatus': ETP_CONF_DIR+"/code", 'systemroot': rootdir, # default system root 'uid': os.getuid(), # current running UID 'entropygid': None, 'sysgroup': "entropy", 'defaultumask': 022, 'storeumask': 002, 'gentle_nice': 15, 'current_nice': 0, 'default_nice': 0, 'server_treeupdatescalled': set(), 'client_treeupdatescalled': set(), 'spm': { 'global_make_conf': "/etc/make.conf", 'global_package_keywords': "/etc/portage/package.keywords", 'global_package_use': "/etc/portage/package.use", 'global_package_mask': "/etc/portage/package.mask", 'global_package_unmask': "/etc/portage/package.unmask", 'global_make_profile': "/etc/make.profile", 'exec': "/usr/bin/emerge", # source package manager executable 'ask_cmd': "--ask", 'pretend_cmd': "--pretend", 'verbose_cmd': "--verbose", 'backend': "portage", 'available_backends': ["portage"], 'cache': {}, 'xpak_entries': { 'description': "DESCRIPTION", 'homepage': "HOMEPAGE", 'chost': "CHOST", 'category': "CATEGORY", 'cflags': "CFLAGS", 'cxxflags': "CXXFLAGS", 'license': "LICENSE", 'src_uri': "SRC_URI", 'use': "USE", 'iuse': "IUSE", 'slot': "SLOT", 'provide': "PROVIDE", 'depend': "DEPEND", 'rdepend': "RDEPEND", 'pdepend': "PDEPEND", 'needed': "NEEDED", 'inherited': "INHERITED", 'keywords': "KEYWORDS", 'contents': "CONTENTS", 'counter': "COUNTER" }, 'system_packages': [ "sys-kernel/linux-sabayon", # our kernel "dev-db/sqlite", # our interface "dev-python/pysqlite", # our python interface to our interface "virtual/cron", # our cron service "app-admin/equo", # our package manager (client) "sys-apps/entropy" # our package manager (server+client) ], 'ignore-spm-downgrades': False, }, 'downloadspeedlimit': None, # equo packages download speed limit (in kb/sec) 'dumpstoragedir': ETP_DIR+ETP_CACHESDIR, # data storage directory, useful to speed up equo across multiple issued commands 'securitydir': ETP_DIR+ETP_SECURITYDIR, # where GLSAs are stored 'securityurl': "http://packages.sabayonlinux.org/security/security-advisories.tar.bz2", # packages keywords/mask/unmask settings 'packagemasking': None, # package masking information dictionary filled by the masking parser 'live_packagemasking': { 'unmask_matches': set(), 'mask_matches': set(), }, 'packagemaskingreasons': { 0: _('reason not available'), 1: _('user package.mask'), 2: _('system keywords'), 3: _('user package.unmask'), 4: _('user repo package.keywords (all packages)'), 5: _('user repo package.keywords'), 6: _('user package.keywords'), 7: _('completely masked'), 8: _('repository general packages.db.mask'), 9: _('repository in branch packages.db.mask'), 10: _('user license.mask'), 11: _('user live unmask'), 12: _('user live mask'), }, 'misc_counters': { 'forced_atoms_update_ids': { '__idtype__': 1, 'kde': 1, }, }, # packages whose need their other installs (different tag), to be removed 'conflicting_tagged_packages': { 'x11-drivers/nvidia-drivers': ['x11-drivers/nvidia-drivers'], 'x11-drivers/ati-drivers': ['x11-drivers/ati-drivers'], }, 'clientserverrepoid': "__system__", 'clientdbid': "client", 'serverdbid': "etpdb:", 'genericdbid': "generic", 'systemreleasefile': "/etc/sabayon-release", 'socket_service': { 'hostname': "localhost", 'port': 1026, 'timeout': 200, 'threads': 5, 'session_ttl': 120, 'default_uid': 0, 'max_connections': 5, 'disabled_cmds': set(), 'ip_blacklist': set(), 'ssl_key': ETP_CONF_DIR+"/socket_server.key", 'ssl_cert': ETP_CONF_DIR+"/socket_server.crt", 'ssl_port': 1027, 'answers': { 'ok': chr(0)+"OK"+chr(0), # command run 'er': chr(0)+"ER"+chr(1), # execution error 'no': chr(0)+"NO"+chr(2), # not allowed 'cl': chr(0)+"CL"+chr(3), # close connection 'mcr': chr(0)+"MCR"+chr(4), # max connections reached 'eos': chr(0) # end of size }, }, # handler settings 'handlers': { 'md5sum': "md5sum.php?arch="+etpSys['arch']+"&package=", # md5sum handler, # XXX: hardcoded? 'errorsend': "http://svn.sabayonlinux.org/entropy/standard/sabayonlinux.org/handlers/http_error_report.php", }, } # set current nice level try: myConst['current_nice'] = os.nice(0) except OSError: pass etpConst.update(myConst) def const_setNiceLevel(low = 0): default_nice = etpConst['default_nice'] current_nice = etpConst['current_nice'] delta = current_nice - default_nice try: etpConst['current_nice'] = os.nice(delta*-1+low) except OSError: pass return current_nice def const_readRepositoriesSettings(): etpRepositories.clear() etpRepositoriesExcluded.clear() del etpRepositoriesOrder[:] if os.path.isfile(etpConst['repositoriesconf']): f = open(etpConst['repositoriesconf'],"r") repositoriesconf = f.readlines() f.close() # setup product first for line in repositoriesconf: if (line.strip().find("product|") != -1) and (not line.strip().startswith("#")) and (len(line.strip().split("|")) == 2): etpConst['product'] = line.strip().split("|")[1] for line in repositoriesconf: line = line.strip() # populate etpRepositories if (line.find("repository|") != -1) and (len(line.split("|")) == 5): excluded = False myRepodata = etpRepositories if line.startswith("##"): continue elif line.startswith("#"): excluded = True myRepodata = etpRepositoriesExcluded line = line[1:] reponame = line.split("|")[1] repodesc = line.split("|")[2] repopackages = line.split("|")[3] repodatabase = line.split("|")[4] eapi3_port = None eapi3_formatcolon = repodatabase.rfind("#") if eapi3_formatcolon != -1: try: eapi3_port = int(repodatabase[eapi3_formatcolon+1:]) repodatabase = repodatabase[:eapi3_formatcolon] except (ValueError, IndexError,): eapi3_port = int(etpConst['socket_service']['port']) else: eapi3_port = int(etpConst['socket_service']['port']) dbformat = etpConst['etpdatabasefileformat'] dbformatcolon = repodatabase.rfind("#") if dbformatcolon != -1: if dbformat in etpConst['etpdatabasesupportedcformats']: try: dbformat = repodatabase[dbformatcolon+1:] except: pass repodatabase = repodatabase[:dbformatcolon] if ((repopackages.startswith("http://") or repopackages.startswith("ftp://") or repopackages.startswith("file://")) and \ (repodatabase.startswith("http://") or repodatabase.startswith("ftp://") or repodatabase.startswith("file://"))) or \ ((not repodatabase) and (myRepodata.has_key(reponame))): if not myRepodata.has_key(reponame): myRepodata[reponame] = {} myRepodata[reponame]['service_port'] = eapi3_port myRepodata[reponame]['description'] = repodesc myRepodata[reponame]['packages'] = [] myRepodata[reponame]['plain_packages'] = [] myRepodata[reponame]['dbpath'] = etpConst['etpdatabaseclientdir']+"/"+reponame+"/"+etpConst['product']+"/"+etpConst['currentarch'] myRepodata[reponame]['dbcformat'] = dbformat myRepodata[reponame]['plain_database'] = repodatabase myRepodata[reponame]['database'] = repodatabase+"/"+etpConst['product']+"/"+reponame+"/database/"+etpConst['currentarch'] myRepodata[reponame]['dbrevision'] = "0" dbrevision_file = os.path.join(myRepodata[reponame]['dbpath'],etpConst['etpdatabaserevisionfile']) if os.path.isfile(dbrevision_file): rev_file = open(dbrevision_file,"r") myRepodata[reponame]['dbrevision'] = rev_file.readline().strip() rev_file.close() del rev_file # initialize CONFIG_PROTECT - will be filled the first time the db will be opened myRepodata[reponame]['configprotect'] = None myRepodata[reponame]['configprotectmask'] = None if not excluded: etpRepositoriesOrder.append(reponame) for x in repopackages.split(): myRepodata[reponame]['plain_packages'].append(x) myRepodata[reponame]['packages'].append(x+"/"+etpConst['product']+"/"+reponame) elif (line.find("branch|") != -1) and (not line.startswith("#")) and (len(line.split("|")) == 2): branch = line.split("|")[1] etpConst['branch'] = branch if not os.path.isdir(etpConst['packagesbindir']+"/"+branch): if etpConst['uid'] == 0: # check if we have a broken symlink os.makedirs(etpConst['packagesbindir']+"/"+branch) elif (line.find("officialrepositoryid|") != -1) and (not line.startswith("#")) and (len(line.split("|")) == 2): officialreponame = line.split("|")[1] etpConst['officialrepositoryid'] = officialreponame elif (line.find("conntestlink|") != -1) and (not line.startswith("#")) and (len(line.split("|")) == 2): conntestlink = line.split("|")[1] etpConst['conntestlink'] = conntestlink elif (line.find("downloadspeedlimit|") != -1) and (not line.startswith("#")) and (len(line.split("|")) == 2): try: myval = int(line.split("|")[1]) if myval > 0: etpConst['downloadspeedlimit'] = myval else: etpConst['downloadspeedlimit'] = None except (ValueError,IndexError,): etpConst['downloadspeedlimit'] = None elif (line.find("securityurl|") != -1) and (not line.startswith("#")) and (len(line.split("|")) == 2): try: url = line.split("|")[1] etpConst['securityurl'] = url except: pass def const_readSocketSettings(): if os.path.isfile(etpConst['socketconf']): f = open(etpConst['socketconf'],"r") socketconf = f.readlines() f.close() for line in socketconf: if line.startswith("listen|") and (len(line.split("|")) > 1): x = line.split("|")[1].strip() if x: etpConst['socket_service']['hostname'] = x elif line.startswith("listen-port|") and (len(line.split("|")) > 1): x = line.split("|")[1].strip() try: x = int(x) etpConst['socket_service']['port'] = x except ValueError: pass elif line.startswith("listen-timeout|") and (len(line.split("|")) > 1): x = line.split("|")[1].strip() try: x = int(x) etpConst['socket_service']['timeout'] = x except ValueError: pass elif line.startswith("listen-threads|") and (len(line.split("|")) > 1): x = line.split("|")[1].strip() try: x = int(x) etpConst['socket_service']['threads'] = x except ValueError: pass elif line.startswith("session-ttl|") and (len(line.split("|")) > 1): x = line.split("|")[1].strip() try: x = int(x) etpConst['socket_service']['session_ttl'] = x except ValueError: pass elif line.startswith("max-connections|") and (len(line.split("|")) > 1): x = line.split("|")[1].strip() try: x = int(x) etpConst['socket_service']['max_connections'] = x except ValueError: pass elif line.startswith("ssl-port|") and (len(line.split("|")) > 1): x = line.split("|")[1].strip() try: x = int(x) etpConst['socket_service']['ssl_port'] = x except ValueError: pass elif line.startswith("disabled-commands|") and (len(line.split("|")) > 1): x = line.split("|")[1].strip().split() for y in x: etpConst['socket_service']['disabled_cmds'].add(y) elif line.startswith("ip-blacklist|") and (len(line.split("|")) > 1): x = line.split("|")[1].strip().split() for y in x: etpConst['socket_service']['ip_blacklist'].add(y) def const_readEntropySettings(): # entropy section if os.path.isfile(etpConst['entropyconf']): const_secure_config_file(etpConst['entropyconf']) f = open(etpConst['entropyconf'],"r") entropyconf = f.readlines() f.close() for line in entropyconf: if line.startswith("loglevel|") and (len(line.split("loglevel|")) == 2): loglevel = line.split("loglevel|")[1] try: loglevel = int(loglevel) except ValueError: pass if (loglevel > -1) and (loglevel < 3): etpConst['entropyloglevel'] = loglevel elif line.startswith("ftp-proxy|") and (len(line.split("|")) == 2): ftpproxy = line.split("|")[1].strip().split() if ftpproxy: etpConst['proxy']['ftp'] = ftpproxy[-1] elif line.startswith("http-proxy|") and (len(line.split("|")) == 2): httpproxy = line.split("|")[1].strip().split() if httpproxy: etpConst['proxy']['http'] = httpproxy[-1] elif line.startswith("proxy-username|") and (len(line.split("|")) == 2): httpproxy = line.split("|")[1].strip().split() if httpproxy: etpConst['proxy']['username'] = httpproxy[-1] elif line.startswith("proxy-password|") and (len(line.split("|")) == 2): httpproxy = line.split("|")[1].strip().split() if httpproxy: etpConst['proxy']['password'] = httpproxy[-1] elif line.startswith("system-name|") and (len(line.split("|")) == 2): etpConst['systemname'] = line.split("|")[1].strip() elif line.startswith("nice-level|") and (len(line.split("|")) == 2): mylevel = line.split("|")[1].strip() try: mylevel = int(mylevel) if (mylevel >= -19) and (mylevel <= 19): const_setNiceLevel(mylevel) except (ValueError,): pass def const_readEntropyRelease(): # handle Entropy Version ETP_REVISION_FILE = "../libraries/revision" if not os.path.isfile(ETP_REVISION_FILE): ETP_REVISION_FILE = os.path.join(etpConst['installdir'],'libraries/revision') if os.path.isfile(ETP_REVISION_FILE): f = open(ETP_REVISION_FILE,"r") myrev = f.readline().strip() etpConst['entropyversion'] = myrev def const_readEquoSettings(): # equo section if (os.path.isfile(etpConst['equoconf'])): f = open(etpConst['equoconf'],"r") equoconf = f.readlines() f.close() for line in equoconf: if line.startswith("loglevel|") and (len(line.split("loglevel|")) == 2): loglevel = line.split("loglevel|")[1] try: loglevel = int(loglevel) except: pass if (loglevel > -1) and (loglevel < 3): etpConst['equologlevel'] = loglevel elif line.startswith("gentoo-compat|") and (len(line.split("|")) == 2): compatopt = line.split("|")[1].strip() if compatopt.lower() in ("disable","disabled","false","0","no"): etpConst['gentoo-compat'] = False else: etpConst['gentoo-compat'] = True elif line.startswith("filesbackup|") and (len(line.split("|")) == 2): compatopt = line.split("|")[1].strip() if compatopt.lower() in ("disable","disabled","false","0","no"): etpConst['filesbackup'] = False elif line.startswith("ignore-spm-downgrades|") and (len(line.split("|")) == 2): compatopt = line.split("|")[1].strip() if compatopt.lower() in ("enable","enabled","true","1","yes"): etpConst['spm']['ignore-spm-downgrades'] = True elif line.startswith("collisionprotect|") and (len(line.split("|")) == 2): collopt = line.split("|")[1].strip() if collopt.lower() in ("0","1","2",): etpConst['collisionprotect'] = int(collopt) elif line.startswith("configprotect|") and (len(line.split("|")) == 2): configprotect = line.split("|")[1].strip() for x in configprotect.split(): etpConst['configprotect'].append(unicode(x,'raw_unicode_escape')) elif line.startswith("configprotectmask|") and (len(line.split("|")) == 2): configprotect = line.split("|")[1].strip() for x in configprotect.split(): etpConst['configprotectmask'].append(unicode(x,'raw_unicode_escape')) elif line.startswith("configprotectskip|") and (len(line.split("|")) == 2): configprotect = line.split("|")[1].strip() for x in configprotect.split(): etpConst['configprotectskip'].append(etpConst['systemroot']+x) def const_setupEntropyPid(just_read = False): if ("--no-pid-handling" in sys.argv) and (not just_read): return # PID creation pid = os.getpid() if os.path.isfile(etpConst['pidfile']): f = open(etpConst['pidfile'],"r") foundPid = str(f.readline().strip()) f.close() if foundPid != str(pid): # is foundPid still running ? if os.path.isdir("%s/proc/%s" % (etpConst['systemroot'],foundPid,)): etpConst['applicationlock'] = True elif not just_read: # if root, write new pid #if etpConst['uid'] == 0: if os.access(etpConst['pidfile'],os.W_OK): try: f = open(etpConst['pidfile'],"w") f.write(str(pid)) f.flush() f.close() except IOError, e: if e.errno == 30: # readonly filesystem pass else: raise try: const_chmod_entropy_pid() except OSError: pass elif not just_read: #if etpConst['uid'] == 0: if os.access(os.path.dirname(etpConst['pidfile']),os.W_OK): if os.path.exists(etpConst['pidfile']): if os.path.islink(etpConst['pidfile']): os.remove(etpConst['pidfile']) elif os.path.isdir(etpConst['pidfile']): import shutil shutil.rmtree(etpConst['pidfile']) f = open(etpConst['pidfile'],"w") f.write(str(pid)) f.flush() f.close() try: const_chmod_entropy_pid() except OSError: pass def const_secure_config_file(config_file): try: mygid = const_get_entropy_gid() except KeyError: mygid = 0 try: const_setup_file(config_file, mygid, 0660) except (OSError, IOError,): pass def const_chmod_entropy_pid(): try: mygid = const_get_entropy_gid() except KeyError: mygid = 0 const_setup_file(etpConst['pidfile'], mygid, 0664) def const_createWorkingDirectories(): # handle pid file piddir = os.path.dirname(etpConst['pidfile']) if not os.path.exists(piddir) and (etpConst['uid'] == 0): os.makedirs(piddir) # create user if it doesn't exist gid = None try: gid = const_get_entropy_gid() except KeyError: if etpConst['uid'] == 0: # create group # avoid checking cause it's not mandatory for entropy/equo itself const_add_entropy_group() try: gid = const_get_entropy_gid() except KeyError: pass # Create paths for x in etpConst: if (type(etpConst[x]) is basestring): if not etpConst[x] or \ etpConst[x].endswith(".conf") or \ not os.path.isabs(etpConst[x]) or \ etpConst[x].endswith(".cfg") or \ etpConst[x].endswith(".tmp") or \ etpConst[x].find(".db") != -1 or \ etpConst[x].find(".log") != -1 or \ os.path.isdir(etpConst[x]) or \ not x.endswith("dir"): continue # allow users to create dirs in custom paths, # so don't fail here even if we don't have permissions try: os.makedirs(etpConst[x]) except OSError: pass if gid: etpConst['entropygid'] = gid ''' change permissions of: /var/lib/entropy /var/tmp/entropy ''' if not os.path.isdir(etpConst['entropyworkdir']): try: os.makedirs(etpConst['entropyworkdir']) except OSError: pass w_gid = os.stat(etpConst['entropyworkdir'])[stat.ST_GID] if w_gid != gid: const_setup_perms(etpConst['entropyworkdir'],gid) if not os.path.isdir(etpConst['entropyunpackdir']): try: os.makedirs(etpConst['entropyunpackdir']) except OSError: pass try: w_gid = os.stat(etpConst['entropyunpackdir'])[stat.ST_GID] if w_gid != gid: if os.path.isdir(etpConst['entropyunpackdir']): const_setup_perms(etpConst['entropyunpackdir'],gid) except OSError: pass # always setup /var/lib/entropy/client permissions if not const_islive(): # aufs/unionfs will start to leak otherwise const_setup_perms(etpConst['etpdatabaseclientdir'],gid) def const_configureLockPaths(): etpConst['locks'] = { 'using_resources': os.path.join(etpConst['etpdatabaseclientdir'],'.using_resources'), } def const_readActivatorSettings(): if os.path.isfile(etpConst['activatorconf']): f = open(etpConst['activatorconf'],"r") actconffile = f.readlines() f.close() for line in actconffile: line = line.strip() if line.startswith("database-format|") and (len(line.split("database-format|")) == 2): format = line.split("database-format|")[1] if format in etpConst['etpdatabasesupportedcformats']: etpConst['etpdatabasefileformat'] = format def const_readReagentSettings(): if (os.path.isfile(etpConst['reagentconf'])): f = open(etpConst['reagentconf'],"r") reagentconf = f.readlines() f.close() for line in reagentconf: if line.startswith("rss-feed|") and (len(line.split("rss-feed|")) == 2): feed = line.split("rss-feed|")[1] if feed in ("enable","enabled","true","1"): etpConst['rss-feed'] = True elif feed in ("disable","disabled","false","0","no",): etpConst['rss-feed'] = False elif line.startswith("rss-name|") and (len(line.split("rss-name|")) == 2): feedname = line.split("rss-name|")[1].strip() etpConst['rss-name'] = feedname elif line.startswith("rss-base-url|") and (len(line.split("rss-base-url|")) == 2): etpConst['rss-base-url'] = line.split("rss-base-url|")[1].strip() if not etpConst['rss-base-url'][-1] == "/": etpConst['rss-base-url'] += "/" elif line.startswith("rss-website-url|") and (len(line.split("rss-website-url|")) == 2): etpConst['rss-website-url'] = line.split("rss-website-url|")[1].strip() elif line.startswith("managing-editor|") and (len(line.split("managing-editor|")) == 2): etpConst['rss-managing-editor'] = line.split("managing-editor|")[1].strip() elif line.startswith("max-rss-entries|") and (len(line.split("max-rss-entries|")) == 2): try: entries = int(line.split("max-rss-entries|")[1].strip()) etpConst['rss-max-entries'] = entries except ValueError: pass elif line.startswith("max-rss-light-entries|") and (len(line.split("max-rss-light-entries|")) == 2): try: entries = int(line.split("max-rss-light-entries|")[1].strip()) etpConst['rss-light-max-entries'] = entries except ValueError: pass def const_readServerSettings(): if not os.access(etpConst['serverconf'],os.R_OK): return etpConst['server_repositories'].clear() f = open(etpConst['serverconf'],"r") serverconf = f.readlines() f.close() for line in serverconf: if line.startswith("branches|") and (len(line.split("branches|")) == 2): branches = line.split("branches|")[1] etpConst['branches'] = [] for branch in branches.split(): etpConst['branches'].append(branch) if etpConst['branch'] not in etpConst['branches']: etpConst['branches'].append(etpConst['branch']) elif (line.find("officialserverrepositoryid|") != -1) and (not line.startswith("#")) and (len(line.split("|")) == 2): etpConst['officialserverrepositoryid'] = line.split("|")[1].strip() elif line.startswith("repository|") and (len(line.split("|")) == 5): repoid = line.split("|")[1].strip() repodesc = line.split("|")[2].strip() repouris = line.split("|")[3].strip() repohandlers = line.split("|")[4].strip() if repouris.startswith("ftp://"): if not etpConst['server_repositories'].has_key(repoid): etpConst['server_repositories'][repoid] = {} etpConst['server_repositories'][repoid]['description'] = repodesc etpConst['server_repositories'][repoid]['mirrors'] = [] etpConst['server_repositories'][repoid]['community'] = False if repohandlers: repohandlers = os.path.join(repohandlers,etpConst['product'],repoid,"handlers") etpConst['server_repositories'][repoid]['handler'] = repohandlers uris = repouris.split() for uri in uris: etpConst['server_repositories'][repoid]['mirrors'].append(uri) const_configureServerRepoPaths() def const_configureServerRepoPaths(): #'packagesserverstoredir': ETP_DIR+"/server/"+ETP_DBREPODIR+"/"+ETP_STOREDIR, #'packagesserveruploaddir': ETP_DIR+"/server/"+ETP_DBREPODIR+"/"+ETP_UPLOADDIR, #'packagesserverbindir': ETP_DIR+"/server/"+ETP_DBREPODIR+"/"+ETP_REPODIR, #'etpdatabasedir': ETP_DIR+"/server/"+ETP_DBREPODIR+"/"+ETP_DBDIR, #'etpdatabasefilepath': ETP_DIR+"/server/"+ETP_DBREPODIR+"/"+ETP_DBDIR+"/"+ETP_DBFILE, # etpConst['server_repositories'] for repoid in etpConst['server_repositories']: etpConst['server_repositories'][repoid]['packages_dir'] = \ os.path.join( etpConst['entropyworkdir'], "server", repoid, "packages", etpSys['arch'] ) etpConst['server_repositories'][repoid]['store_dir'] = \ os.path.join( etpConst['entropyworkdir'], "server", repoid, "store", etpSys['arch'] ) etpConst['server_repositories'][repoid]['upload_dir'] = \ os.path.join( etpConst['entropyworkdir'], "server", repoid, "upload", etpSys['arch'] ) etpConst['server_repositories'][repoid]['database_dir'] = \ os.path.join( etpConst['entropyworkdir'], "server", repoid, "database", etpSys['arch'] ) etpConst['server_repositories'][repoid]['packages_relative_path'] = \ os.path.join( etpConst['product'], repoid, "packages", etpSys['arch'] )+"/" etpConst['server_repositories'][repoid]['database_relative_path'] = \ os.path.join( etpConst['product'], repoid, "database", etpSys['arch'] )+"/" def const_setupWithEnvironment(): shell_repoid = os.getenv('ETP_REPO') if shell_repoid: etpConst['officialserverrepositoryid'] = shell_repoid expiration_days = os.getenv('ETP_EXPIRATION_DAYS') if expiration_days: try: expiration_days = int(expiration_days) etpConst['packagesexpirationdays'] = expiration_days except ValueError: pass def const_setup_perms(mydir, gid): if gid == None: return for currentdir,subdirs,files in os.walk(mydir): try: cur_gid = os.stat(currentdir)[stat.ST_GID] if cur_gid != gid: os.chown(currentdir,-1,gid) cur_mod = const_get_chmod(currentdir) if cur_mod != oct(0775): os.chmod(currentdir,0775) except OSError: pass for item in files: item = os.path.join(currentdir,item) try: const_setup_file(item, gid, 0664) except OSError: pass def const_setup_file(myfile, gid, chmod): cur_gid = os.stat(myfile)[stat.ST_GID] if cur_gid != gid: os.chown(myfile,-1,gid) cur_mod = const_get_chmod(myfile) if cur_mod != oct(chmod): os.chmod(myfile,chmod) # you need to convert to int def const_get_chmod(item): st = os.stat(item)[stat.ST_MODE] return oct(st & 0777) def const_get_entropy_gid(): group_file = os.path.join(etpConst['systemroot'],'/etc/group') if not os.path.isfile(group_file): raise KeyError f = open(group_file,"r") for line in f.readlines(): if line.startswith('%s:' % (etpConst['sysgroup'],)): try: gid = int(line.split(":")[2]) except ValueError: raise KeyError return gid raise KeyError def const_add_entropy_group(): group_file = os.path.join(etpConst['systemroot'],'/etc/group') if not os.path.isfile(group_file): raise KeyError ids = set() f = open(group_file,"r") for line in f.readlines(): if line and line.split(":"): try: myid = int(line.split(":")[2]) except ValueError: pass ids.add(myid) if ids: # starting from 1000, get the first free while 1: new_id = 1000 if new_id not in ids: break else: new_id = 10000 f.close() f = open(group_file,"aw") f.seek(0,2) app_line = "entropy:x:%s:\n" % (new_id,) f.write(app_line) f.flush() f.close() def const_islive(): if not os.path.isfile("/proc/cmdline"): return False f = open("/proc/cmdline") cmdline = f.readline().strip().split() f.close() if "cdroot" in cmdline: return True return False # load config initConfig_entropyConstants(etpSys['rootdir'])