From 1ceb8beae0695fc8468f75f7b689bf7b7903802f Mon Sep 17 00:00:00 2001 From: "(no author)" <(no author)@cd1c1023-2f26-0410-ae45-c471fc1f0318> Date: Wed, 10 Oct 2007 23:39:34 +0000 Subject: [PATCH] - completed elog infrastructure - implemented messages support inside database - implemented messages database API - wrote postinstall preliminary infrastructure with fonts,gcc,icons support git-svn-id: http://svn.sabayonlinux.org/projects/entropy/trunk@546 cd1c1023-2f26-0410-ae45-c471fc1f0318 --- TODO | 6 +-- client/equo | 2 +- client/equoTools.py | 13 +++++- client/triggerTools.py | 88 ++++++++++++++++++++++++++++------- libraries/databaseTools.py | 56 +++++++++++++++++++++- libraries/entropyConstants.py | 3 +- libraries/entropyTools.py | 23 +++++++++ libraries/reagentTools.py | 23 +++++++++ 8 files changed, 188 insertions(+), 26 deletions(-) diff --git a/TODO b/TODO index c9210aa63..544d0bf59 100644 --- a/TODO +++ b/TODO @@ -1,7 +1,6 @@ TODO list: - reagent: complete smartapps section CLIENT: - - trap elogs in reagent - complete etc-update alike support - add disk caching support to slow functions - add preinst/postinst/prerm/postrm scripts @@ -11,9 +10,6 @@ TODO list: - desktop mime database - shared mime database - scrollkeeper database - - icons cache - - fonts cache (run mkfontdir after writes in /usr/share/fonts) - - switch gcc profile (when installing one) - switch binutils profile - kernel modules (depmod and moduledb) - world upgrade should switch python to 2.5 @@ -29,4 +25,4 @@ Project Status: - reagent: complete. Bug fixing mode. - activator: complete. Bug fixing mode. ============ -- client part: 70% \ No newline at end of file +- client part: 75% \ No newline at end of file diff --git a/client/equo b/client/equo index 939443499..384c31b0c 100644 --- a/client/equo +++ b/client/equo @@ -153,7 +153,7 @@ try: import confTools scandata = confTools.scanfs(quiet = True, dcache = True) if len(scandata) > 0: - print_warning(darkgreen("There are "+str(len(scandata))+" configuration files that need(s) to be updated.")) + print_warning(darkgreen("There are "+str(len(scandata))+" configuration file(s) that need(s) to be updated.")) print_warning(red("Please run: ")+bold("etc-update")) # FIXME: add our tool sys.exit(rc) diff --git a/client/equoTools.py b/client/equoTools.py index eb21cbc3f..22ce57f1d 100644 --- a/client/equoTools.py +++ b/client/equoTools.py @@ -2110,6 +2110,7 @@ def installPackages(packages = [], atomsdata = [], ask = False, pretend = False, pkgfile = dbconn.retrieveDownloadURL(packageInfo[0]) pkgcat = dbconn.retrieveCategory(packageInfo[0]) pkgname = dbconn.retrieveName(packageInfo[0]) + pkgmessages = dbconn.retrieveMessages(packageInfo[0]) onDiskUsedSize += dbconn.retrieveOnDiskSize(packageInfo[0]) # fill action queue @@ -2124,6 +2125,7 @@ def installPackages(packages = [], atomsdata = [], ask = False, pretend = False, actionQueue[pkgatom]['removeidpackage'] = -1 actionQueue[pkgatom]['download'] = pkgfile actionQueue[pkgatom]['checksum'] = pkgdigest + actionQueue[pkgatom]['messages'] = pkgmessages actionQueue[pkgatom]['removeconfig'] = configFiles dl = checkNeededDownload(pkgfile, pkgdigest) actionQueue[pkgatom]['fetch'] = dl @@ -2256,6 +2258,7 @@ def installPackages(packages = [], atomsdata = [], ask = False, pretend = False, steps.append("preinstall") steps.append("install") steps.append("postinstall") + steps.append("showmessages") #print "steps for "+pkgatom+" -> "+str(steps) print_info(red(" @@ ")+bold("(")+blue(str(currentqueue))+"/"+red(totalqueue)+bold(") ")+">>> "+darkgreen(pkgatom)) @@ -2457,7 +2460,6 @@ def dependenciesTest(quiet = False, ask = False, pretend = False): deptree, status = generateDependencyTree([xidpackage,0]) if (status == 0): - # skip conflicts conflicts = deptree.get(0,None) if (conflicts): @@ -2558,11 +2560,18 @@ def stepExecutor(step,infoDict): errormsg = red("An error occured while trying to remove the package. Check if you have enough disk space on your hard disk. Error "+str(output)) print_error(errormsg) + elif step == "showmessages": + # get messages + for msg in infoDict['messages']: # FIXME: add logging support + print_warning(brown(' ## ')+msg) + elif step == "postinstall": # analyze atom pkgdata = etpInstallTriggers.get(infoDict['atom']) if pkgdata: - triggerTools.postinstall(pkgdata) + triggers = triggerTools.postinstall(pkgdata) + for trigger in triggers: # code reuse, we'll fetch triggers list on the GUI client and run each trigger by itself + eval("triggerTools."+trigger)(pkgdata) #elif step == "preinstall": # analyze atom diff --git a/client/triggerTools.py b/client/triggerTools.py index 673bde81f..0715c6301 100644 --- a/client/triggerTools.py +++ b/client/triggerTools.py @@ -24,31 +24,69 @@ import sys import os sys.path.append('../libraries') from outputTools import * +import entropyTools ''' - @description: pkgdata parser that triggers proper post-install scripts + @description: pkgdata parser that collects post-install scripts that would be run ''' def postinstall(pkgdata): + functions = [] + # fonts configuration if pkgdata['category'] == "media-fonts": - fontdirs = set() - for xdir in pkgdata['content']: - if xdir.startswith("/usr/share/fonts"): - origdir = xdir[16:] - if origdir: - if origdir.startswith("/"): - origdir = origdir.split("/")[1] - if os.path.isdir(xdir[:16]+"/"+origdir): - fontdirs.add(xdir[:16]+"/"+origdir) - if (fontdirs): - print_info(" "+brown("[POST] Configuring fonts directory...")) - for fontdir in fontdirs: - setupfontdir(fontdir) - setupfontcache(fontdir) + functions.append("fontconfig") + + # gcc configuration + if pkgdata['category']+"/"+pkgdata['name'] == "sys-devel/gcc": + functions.append("gccswitch") + + # icons cache setup + mycnt = set(pkgdata['content']) + for file in mycnt: + if file.startswith("/usr/share/icons") and file.endswith("index.theme"): + functions.append('iconscache') + break + + return functions +######################################################## +#### +## Public functions +# + +def fontconfig(pkgdata): + fontdirs = set() + for xdir in pkgdata['content']: + if xdir.startswith("/usr/share/fonts"): + origdir = xdir[16:] + if origdir: + if origdir.startswith("/"): + origdir = origdir.split("/")[1] + if os.path.isdir(xdir[:16]+"/"+origdir): + fontdirs.add(xdir[:16]+"/"+origdir) + if (fontdirs): + print_info(" "+brown("[POST] Configuring fonts directory...")) + for fontdir in fontdirs: + setupfontdir(fontdir) + setupfontcache(fontdir) + +def gccswitch(pkgdata): + print_info(" "+brown("[POST] Configuring GCC Profile...")) + # get gcc profile + pkgsplit = entropyTools.catpkgsplit(pkgdata['category']+"/"+pkgdata['name']+"-"+pkgdata['version']) + profile = pkgdata['chost']+"-"+pkgsplit[2] + setgccprofile(profile) + +def iconscache(pkgdata): + print_info(" "+brown("[POST] Updating icons cache...")) + mycnt = set(pkgdata['content']) + for file in mycnt: + if file.startswith("/usr/share/icons") and file.endswith("index.theme"): + cachedir = os.path.dirname(file) + generateiconscache(cachedir) ######################################################## #### @@ -76,4 +114,22 @@ def setupfontcache(fontdir): # fc-cache -f gooooo! if os.access('/usr/bin/fc-cache',os.X_OK): os.system('HOME="/root" /usr/bin/fc-cache -f '+unicode(fontdir)) - return 0 \ No newline at end of file + return 0 + +''' + @description: set chosen gcc profile + @output: returns int() as exit status +''' +def setgccprofile(profile): + if os.access('/usr/bin/gcc-config',os.X_OK): + os.system('/usr/bin/gcc-config '+profile) + return 0 + +''' + @description: creates/updates icons cache + @output: returns int() as exit status +''' +def generateiconscache(cachedir): + if os.access('/usr/bin/gtk-update-icon-cache',os.X_OK): + os.system('/usr/bin/gtk-update-icon-cache -qf '+cachedir) + return 0 diff --git a/libraries/databaseTools.py b/libraries/databaseTools.py index db666c6e8..d7d034565 100644 --- a/libraries/databaseTools.py +++ b/libraries/databaseTools.py @@ -1077,6 +1077,28 @@ class etpDatabase: atom, ) ) + + # compile messages + try: + for message in etpData['messages']: + self.cursor.execute( + 'INSERT into messages VALUES ' + '(?,?)' + , ( idpackage, + message, + ) + ) + except: + # FIXME: temp workaround, create messages table + self.cursor.execute("CREATE TABLE messages ( idpackage INTEGER, message VARCHAR);") + for message in etpData['messages']: + self.cursor.execute( + 'INSERT into messages VALUES ' + '(?,?)' + , ( idpackage, + message, + ) + ) # is it a system package? if etpData['systempackage']: @@ -1100,7 +1122,7 @@ class etpDatabase: idprotect, ) ) - + idprotect = self.isProtectAvailable(etpData['config_protect_mask']) if (idprotect == -1): # create category @@ -1304,6 +1326,11 @@ class etpDatabase: self.cursor.execute('DELETE FROM keywords WHERE idpackage = '+idpackage) # binkeywords self.cursor.execute('DELETE FROM binkeywords WHERE idpackage = '+idpackage) + try: + # messages + self.cursor.execute('DELETE FROM messages WHERE idpackage = '+idpackage) + except: + pass # FIXME: temp workaround # systempackage self.cursor.execute('DELETE FROM systempackages WHERE idpackage = '+idpackage) try: @@ -1595,6 +1622,7 @@ class etpDatabase: data['digest'] = self.retrieveDigest(idpackage) data['sources'] = self.retrieveSources(idpackage) data['counter'] = self.retrieveCounter(idpackage) + data['messages'] = self.retrieveMessages(idpackage) if (self.isSystemPackage(idpackage)): data['systempackage'] = 'xxx' @@ -1774,6 +1802,32 @@ class etpDatabase: self.databaseCache[int(idpackage)]['retrieveCounter'] = counter return counter + def retrieveMessages(self, idpackage): + dbLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_VERBOSE,"retrieveMessages: retrieving messages for package ID "+str(idpackage)) + + ''' caching ''' + if (self.xcache): + cached = self.databaseCache.get(int(idpackage), None) + if cached: + rslt = self.databaseCache[int(idpackage)].get('retrieveMessages',None) + if rslt: + return rslt + else: + self.databaseCache[int(idpackage)] = {} + + messages = [] + try: + self.cursor.execute('SELECT "message" FROM messages WHERE idpackage = "'+str(idpackage)+'"') + for row in self.cursor: + messages.append(row[0]) + except: + pass + + ''' caching ''' + if (self.xcache): + self.databaseCache[int(idpackage)]['retrieveMessages'] = messages + return messages + # in bytes def retrieveSize(self, idpackage): dbLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_VERBOSE,"retrieveSize: retrieving Size for package ID "+str(idpackage)) diff --git a/libraries/entropyConstants.py b/libraries/entropyConstants.py index ba063c069..ec41c1cd2 100644 --- a/libraries/entropyConstants.py +++ b/libraries/entropyConstants.py @@ -62,6 +62,7 @@ etpData = { '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 } # Entropy database SQL initialization Schema and data structure @@ -338,7 +339,7 @@ etpConst = { 'entropyloglevel': 1, # # Entropy log level (default: 1 - see entropy.conf for more info) 'equologlevel': 1, # # Equo log level (default: 1 - see equo.conf for more info) 'spmbackendloglevel': 1, # # Source Package Manager backend log level (default: 1 - see entropy.conf for more info) - 'logdir': ETP_LOG_DIR , # Log dir where ebuilds store their shit + 'logdir': ETP_LOG_DIR , # Log dir where ebuilds store their stuff 'syslogdir': ETP_SYSLOG_DIR, # Entropy system tools log directory 'mirrorslogfile': ETP_SYSLOG_DIR+"/mirrors.log", # Mirrors operations log file diff --git a/libraries/entropyTools.py b/libraries/entropyTools.py index 2304d85d6..03f976eb6 100644 --- a/libraries/entropyTools.py +++ b/libraries/entropyTools.py @@ -287,6 +287,29 @@ def allocateMaskedFile(file): newfile = previousfile return newfile +def extractElog(file): + + entropyLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_VERBOSE,"extractElog: called.") + + logline = False + logoutput = [] + f = open(file,"r") + reallog = f.readlines() + f.close() + + for line in reallog: + if line.startswith("INFO: postinst") or line.startswith("LOG: postinst"): + logline = True + continue + # disable all the others + elif line.startswith("INFO:") or line.startswith("LOG:"): + logline = False + continue + if (logline) and (line.strip()): + # trap ! + logoutput.append(line.strip()) + return logoutput + # Imported from Gentoo portage_dep.py # Copyright 2003-2004 Gentoo Foundation # done to avoid the import of portage_dep here diff --git a/libraries/reagentTools.py b/libraries/reagentTools.py index c752f53cb..63c02403e 100644 --- a/libraries/reagentTools.py +++ b/libraries/reagentTools.py @@ -679,6 +679,29 @@ def extractPkgData(package, etpBranch = etpConst['branch']): protect, mask = getConfigProtectAndMask() etpData['config_protect'] = protect etpData['config_protect_mask'] = mask + + # fill etpData['messages'] + # etpConst['logdir']+"/elog" + etpData['messages'] = [] + if os.path.isdir(etpConst['logdir']+"/elog"): + elogfiles = os.listdir(etpConst['logdir']+"/elog") + myelogfile = etpData['category']+":"+etpData['name']+"-"+etpData['version'] + foundfiles = [] + for file in elogfiles: + if file.startswith(myelogfile): + foundfiles.append(file) + if foundfiles: + elogfile = foundfiles[0] + if len(foundfiles) > 1: + # get the latest + mtimes = [] + for file in foundfiles: + mtimes.append((getFileUnixMtime(etpConst['logdir']+"/elog/"+file),file)) + mtimes.sort() + elogfile = mtimes[len(mtimes)-1][1] + etpData['messages'] = extractElog(etpConst['logdir']+"/elog/"+elogfile) + else: + print_warning(red(etpConst['logdir']+"/elog")+" not set, have you configured make.conf properly?") print_info(yellow(" * ")+red(info_package+"Getting Entropy API version..."),back = True) # write API info