- 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
This commit is contained in:
@@ -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%
|
||||
- client part: 75%
|
||||
+1
-1
@@ -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)
|
||||
|
||||
|
||||
+11
-2
@@ -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
|
||||
|
||||
+72
-16
@@ -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
|
||||
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
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user