- 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:
4
TODO
4
TODO
@@ -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
|
||||
|
||||
@@ -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":
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;')
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
@@ -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)
|
||||
Reference in New Issue
Block a user