- fixed a various range of bugs

- implemented external triggers support
- implemented xterm title printouts


git-svn-id: http://svn.sabayonlinux.org/projects/entropy/trunk@654 cd1c1023-2f26-0410-ae45-c471fc1f0318
This commit is contained in:
(no author)
2007-11-11 13:40:39 +00:00
parent 0d9b8159d1
commit 767ef9fbc7
8 changed files with 136 additions and 54 deletions

4
TODO
View File

@@ -1,7 +1,5 @@
TODO list:
CLIENT:
- add external triggerable hooks support
- include more triggers
- use depgraph generation function to generate dependencies
- installPackages should pull conflicts depends too
- find a way to better handle real smartapps deps
@@ -12,6 +10,6 @@ Project Status:
- reagent: complete. Stabilization mode.
- activator: complete. Stabilization mode.
============
- equo (client): 92%
- equo (client): 94%
- EAPI1+ info: http://www.pkgcore.org/trac/pkgcore/doc/doc/extended-atom-syntax.rst

View File

@@ -141,6 +141,7 @@ elif (options[0] == "--info"):
sys.exit(0)
try:
rc = 0
# sync mirrors tool
if (options[0] == "update") or (options[0] == "repoinfo") or (options[0] == "status"):
if options[0] == "update":

View File

@@ -2069,7 +2069,10 @@ def worldUpdate(ask = False, pretend = False, verbose = False, onlyfetch = False
mdbconn = openRepositoryDatabase(matchresults[1])
matchatom = mdbconn.retrieveAtom(matchresults[0])
mdbconn.closeDB()
updateList.add((matchatom,matchresults))
# compare versions
unsatisfied, satisfied = filterSatisfiedDependencies((matchatom,))
if unsatisfied:
updateList.add((matchatom,matchresults))
else:
fineList.add(idpackage)
@@ -2110,7 +2113,7 @@ def worldUpdate(ask = False, pretend = False, verbose = False, onlyfetch = False
time.sleep(5)
# run removePackages with --nodeps
removePackages(atomsdata = removedList, ask = ask, verbose = verbose, deps = False, systemPackagesCheck = False)
removePackages(atomsdata = removedList, ask = ask, verbose = verbose, deps = False, systemPackagesCheck = False, configFiles = True)
else:
print_info(red(" @@ ")+blue("Calculation complete."))
@@ -2461,11 +2464,13 @@ def installPackages(packages = [], atomsdata = [], ask = False, pretend = False,
# running tasks
totalqueue = str(len(runQueue))
totalremovalqueue = str(len(removalQueue))
currentqueue = 0
currentremovalqueue = 0
clientDbconn = openClientDatabase()
for idpackage in removalQueue:
currentremovalqueue += 1
infoDict = {}
infoDict['removeatom'] = clientDbconn.retrieveAtom(idpackage)
infoDict['removecontent'] = clientDbconn.retrieveContent(idpackage)
@@ -2480,7 +2485,7 @@ def installPackages(packages = [], atomsdata = [], ask = False, pretend = False,
steps.append("remove")
steps.append("postremove")
for step in steps:
rc = stepExecutor(step,infoDict)
rc = stepExecutor(step,infoDict,str(currentremovalqueue)+"/"+totalremovalqueue)
if (rc != 0):
clientDbconn.closeDB()
dirscleanup()
@@ -2534,10 +2539,11 @@ def installPackages(packages = [], atomsdata = [], ask = False, pretend = False,
steps.append("showmessages")
#print "steps for "+pkgatom+" -> "+str(steps)
print_info(red(" @@ ")+bold("(")+blue(str(currentqueue))+"/"+red(totalqueue)+bold(") ")+">>> "+darkgreen(pkgatom))
for step in steps:
rc = stepExecutor(step,actionQueue[pkgatom])
rc = stepExecutor(step,actionQueue[pkgatom],str(currentqueue)+"/"+totalqueue)
if (rc != 0):
clientDbconn.closeDB()
dirscleanup()
@@ -2694,7 +2700,9 @@ def removePackages(packages = [], atomsdata = [], ask = False, pretend = False,
for idpackage in plainRemovalQueue:
removalQueue.append(idpackage)
currentqueue = 0
for idpackage in removalQueue:
currentqueue += 1
infoDict = {}
infoDict['removeidpackage'] = idpackage
infoDict['removeatom'] = clientDbconn.retrieveAtom(idpackage)
@@ -2709,7 +2717,7 @@ def removePackages(packages = [], atomsdata = [], ask = False, pretend = False,
steps.append("remove")
steps.append("postremove")
for step in steps:
rc = stepExecutor(step,infoDict)
rc = stepExecutor(step,infoDict,str(currentqueue)+"/"+str(len(removalQueue)))
if (rc != 0):
clientDbconn.closeDB()
return -1,rc
@@ -2807,15 +2815,17 @@ def dependenciesTest(quiet = False, ask = False, pretend = False):
@description: execute the requested step (it is only used by the CLI client)
@input: step -> name of the step to execute
infoDict -> dictionary containing all the needed information collected by installPackages() -> actionQueue[pkgatom]
loopString -> used to print to xterm title bar something like "10/900 - equo"
@output: -1,"description" for error ; 0,True for no errors
'''
def stepExecutor(step,infoDict):
def stepExecutor(step,infoDict, loopString = None):
clientDbconn = openClientDatabase()
output = 0
if step == "fetch":
print_info(red(" ## ")+blue("Fetching package: ")+red(os.path.basename(infoDict['download'])))
print_info(red(" ## ")+blue("Fetching archive: ")+red(os.path.basename(infoDict['download'])))
xtermTitle(loopString+' Fetching archive: '+os.path.basename(infoDict['download']))
output = fetchFileOnMirrors(infoDict['repository'],infoDict['download'],infoDict['checksum'])
if output < 0:
print_error(red("Package cannot be fetched. Try to run: '")+bold("equo update")+red("' and this command again. Error "+str(output)))
@@ -2824,10 +2834,11 @@ def stepExecutor(step,infoDict):
output = matchChecksum(infoDict)
elif step == "install":
compatstring = ''
if (etpConst['gentoo-compat']):
print_info(red(" ## ")+blue("Installing package: ")+red(os.path.basename(infoDict['download']))+" ## w/Gentoo compatibility")
else:
print_info(red(" ## ")+blue("Installing package: ")+red(os.path.basename(infoDict['download'])))
compatstring = " ## w/Gentoo compatibility"
print_info(red(" ## ")+blue("Installing package: ")+red(os.path.basename(infoDict['atom']))+compatstring)
xtermTitle(loopString+' Installing package: '+os.path.basename(infoDict['atom'])+compatstring)
output = installPackage(infoDict)
if output != 0:
if output == 512:
@@ -2841,6 +2852,7 @@ def stepExecutor(step,infoDict):
if (etpConst['gentoo-compat']):
gcompat = " ## w/Gentoo compatibility"
print_info(red(" ## ")+blue("Removing installed package: ")+red(infoDict['removeatom'])+gcompat)
xtermTitle(loopString+' Removing installed package: '+os.path.basename(infoDict['removeatom'])+gcompat)
output = removePackage(infoDict)
if output != 0:
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))

View File

@@ -42,7 +42,10 @@ INITSERVICES_DIR="/var/lib/init.d/"
def postinstall(pkgdata):
functions = set()
if pkgdata['trigger']:
functions.add('call_ext_postinstall')
# fonts configuration
if pkgdata['category'] == "media-fonts":
functions.add("fontconfig")
@@ -118,6 +121,9 @@ def preinstall(pkgdata):
functions = set()
if pkgdata['trigger']:
functions.add('call_ext_preinstall')
# prepare content
mycnt = set(pkgdata['content'])
@@ -135,7 +141,10 @@ def preinstall(pkgdata):
def postremove(pkgdata):
functions = set()
if pkgdata['trigger']:
functions.add('call_ext_postremove')
# opengl configuration
if (pkgdata['category'] == "x11-drivers") and (pkgdata['name'].startswith("nvidia-") or pkgdata['name'].startswith("ati-")):
functions.add("openglsetup_xorg")
@@ -185,6 +194,10 @@ def postremove(pkgdata):
def preremove(pkgdata):
functions = set()
if pkgdata['trigger']:
functions.add('call_ext_preremove')
# prepare content
mycnt = set(pkgdata['removecontent'])
@@ -196,6 +209,42 @@ def preremove(pkgdata):
return functions
########################################################
####
## External triggers support functions
#
def call_ext_preinstall(pkgdata):
rc = call_ext_generic(pkgdata,'preinstall')
return rc
def call_ext_postinstall(pkgdata):
rc = call_ext_generic(pkgdata,'postinstall')
return rc
def call_ext_preremove(pkgdata):
rc = call_ext_generic(pkgdata,'preremove')
return rc
def call_ext_postremove(pkgdata):
rc = call_ext_generic(pkgdata,'postremove')
return rc
def call_ext_generic(pkgdata, stage):
triggerfile = etpConst['entropyunpackdir']+"/trigger-"+str(entropyTools.getRandomNumber())
while os.path.isfile(tmptriggerfile):
triggerfile = etpConst['entropyunpackdir']+"/trigger-"+str(entropyTools.getRandomNumber())
f = open(triggerfile,"w")
for x in pkgdata['trigger']:
f.write(x)
f.close()
execfile(triggerfile)
os.remove(triggerfile)
return my_ext_status
########################################################
####
## Public functions

View File

@@ -1149,14 +1149,26 @@ class etpDatabase:
)
)
# is it a system package?
if etpData['systempackage']:
self.cursor.execute(
'INSERT into systempackages VALUES '
'(?)'
, ( idpackage,
)
)
try:
# is it a system package?
if etpData['systempackage']:
self.cursor.execute(
'INSERT into systempackages VALUES '
'(?)'
, ( idpackage,
)
)
except:
# FIXME: temp workaround, create systempackages table
self.createSystemPackagesTable()
# is it a system package?
if etpData['systempackage']:
self.cursor.execute(
'INSERT into systempackages VALUES '
'(?)'
, ( idpackage,
)
)
# create new protect if it doesn't exist
try:
@@ -1383,8 +1395,11 @@ class etpDatabase:
self.cursor.execute('DELETE FROM messages WHERE idpackage = '+idpackage)
except:
pass
# systempackage
self.cursor.execute('DELETE FROM systempackages WHERE idpackage = '+idpackage)
try:
# systempackage
self.cursor.execute('DELETE FROM systempackages WHERE idpackage = '+idpackage)
except:
pass
try:
# counter
self.cursor.execute('DELETE FROM counters WHERE idpackage = '+idpackage)
@@ -2601,7 +2616,12 @@ class etpDatabase:
cache = self.fetchInfoCache(idpackage,'isSystemPackage')
if cache != None: return cache
self.cursor.execute('SELECT idpackage FROM systempackages WHERE idpackage = "'+str(idpackage)+'"')
try:
self.cursor.execute('SELECT idpackage FROM systempackages WHERE idpackage = "'+str(idpackage)+'"')
except: # FIXME: remove this for 1.0
self.createSystemPackagesTable()
self.cursor.execute('SELECT idpackage FROM systempackages WHERE idpackage = "'+str(idpackage)+'"')
result = self.cursor.fetchone()
rslt = False
if result:
@@ -3128,7 +3148,12 @@ class etpDatabase:
self.cursor.execute('CREATE TABLE needed ( idpackage INTEGER, idneeded INTEGER );')
self.cursor.execute('CREATE TABLE neededreference ( idneeded INTEGER PRIMARY KEY, library VARCHAR );')
self.commitChanges()
def createSystemPackagesTable(self):
dbLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_VERBOSE,"createSystemPackagesTable: called.")
self.cursor.execute('CREATE TABLE systempackages ( idpackage INTEGER );')
self.commitChanges()
def createProtectTable(self):
dbLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_VERBOSE,"createProtectTable: called.")
self.cursor.execute('DROP TABLE IF EXISTS configprotect;')

View File

@@ -1109,6 +1109,7 @@ def umountProc():
return True
def askquestion(prompt):
xtermTitle("Entropy got a question for you")
responses, colours = ["Yes", "No"], [green, red]
print darkgreen(prompt),
try:

View File

@@ -161,13 +161,11 @@ def xtermTitle(mystr, raw=False):
if dotitles and "TERM" in os.environ and sys.stderr.isatty():
myt=os.environ["TERM"]
legal_terms = ["xterm","Eterm","aterm","rxvt","screen","kterm","rxvt-unicode","gnome"]
for term in legal_terms:
if myt.startswith(term):
if not raw:
mystr = "\x1b]0;%s\x07" % mystr
sys.stderr.write(mystr)
sys.stderr.flush()
break
if myt in legal_terms:
if not raw:
mystr = "\x1b]0;%s\x07" % mystr
sys.stderr.write(mystr)
sys.stderr.flush()
default_xterm_title = None
@@ -264,9 +262,7 @@ def print_generic(msg): # here we'll wrap any nice formatting
def writechar(char):
sys.stdout.write(char); sys.stdout.flush()
# function that reads user input printing a request like this:
# Your name: <user input> <ENTER> where "Your name:" is request
# the user input is returned
def readtext(request):
xtermTitle("Entropy needs your attention")
text = raw_input(request)
return text

View File

@@ -8,19 +8,16 @@
@ postinstall(): triggered after injecting data into the database and copying files on the system
@ postremove(): triggered after removing files from the system and from the database
- You are allowed to not specify one or more of them.
- Each function must have as input arguments pkgdata = None. Where pkgdata is a python dict containing package information
>>> databaseTools.etpDatabase.getPackageData(idpackage)
- Each function must return 0 in case of success and >0 in case of issues. Entropy will show the error code to the user.
- You must always specify them.
- Each function can only print errors and ONLY in case of critical ones, return != 0 that will be grabbed by the trigger (setting ext_status)
How it works:
- this file will be stored inside the .tbz2 injected entropy database
- entropy database will be extracted and placed into the unpack directory
- this file will be stored inside the entropy database
- trigger code will be extracted and saved into a file with the name trigger inside the package unpack directory
- will be issued:
stage = 'postinstall' # this can be postinstall, preinstall, postremove, preremove
execfile(etpConst['entropyunpackdir']+...+"trigger")
- code will have access to all the entropy functions and modules. it will be executed inside triggerTools
- code will have access to the entropy package dictionary and will be executed inside triggerTools (postinstall(),preinstall(),postremove(),preremove())
Example of pkgdata:
{
@@ -65,29 +62,32 @@
'''
space for real triggers
'''
def ext_postinstall():
print printhello()+" postinstall"
def ext_postinstall(pkgdata):
print my_ext_printhello()+" postinstall"
return 0
def ext_preinstall():
print printhello()+" preinstall"
def ext_preinstall(pkgdata):
print my_ext_printhello()+" preinstall"
return 0
def ext_postremove():
print printhello()+" postremove"
def ext_postremove(pkgdata):
print my_ext_printhello()+" postremove"
return 0
def ext_preremove():
print printhello()+" preremove"
def ext_preremove(pkgdata):
print my_ext_printhello()+" preremove"
return 0
'''
space for private functions
Important: function must be declared globally and have suffix my_ext_
'''
def printhello():
global my_ext_printhello
def my_ext_printhello():
return "hello!"
'''
run the selected function
'''
eval("ext_"+stage)()
global my_ext_status
my_ext_status = eval("ext_"+stage)(pkgdata)