- fixed a lot of memory leaks

- updated some functions inside triggerTools
- improved speed of content table by indexing the content
- added --resume support for remove,install,world tools 
- removed memory hog contentCache (set())
- some misc fixes

git-svn-id: http://svn.sabayonlinux.org/projects/entropy/trunk@728 cd1c1023-2f26-0410-ae45-c471fc1f0318
This commit is contained in:
(no author)
2007-11-19 04:07:28 +00:00
parent 1d230629b1
commit 3a643f70d8
9 changed files with 830 additions and 703 deletions
+5 -3
View File
@@ -1,12 +1,14 @@
TODO list:
CLIENT:
- give removal depends calculation a bit of love
- better implement --deep (for install)
- implement --skipfirst for world and install/remove
- keep outdated packages on the server for a week
- find a way to better handle real smartapps deps
- add support for database revisions log
- add external trigger for splashutils
- env-update source /etc/profile after install?
- implement --resume and --skipfirst for world and install
- keep outdated packages on the server for a week
Project Status:
+3
View File
@@ -51,6 +51,7 @@ def print_help():
print_info(" \t\t"+red("--verbose")+"\t\t show more details about what's going on")
print_info(" \t\t"+red("--replay")+"\t\t reinstall all the packages and their dependencies")
print_info(" \t\t"+red("--empty")+"\t\t\t same as --replay")
print_info(" \t\t"+red("--resume")+"\t\t resume previously interrupted operations")
print_info(" \t\t"+red("--upgrade")+"\t\t upgrade "+etpConst['systemname']+" to the specified release (3.5,3.6...)")
print_info(" \t"+blue("install")+brown("\t\t install one or more packages or .tbz2"))
@@ -58,6 +59,7 @@ def print_help():
print_info(" \t\t"+red("--pretend")+"\t\t just show what would be done")
print_info(" \t\t"+red("--fetch")+"\t\t\t just download packages without doing the install")
print_info(" \t\t"+red("--nodeps")+"\t\t do not manage any dependency")
print_info(" \t\t"+red("--resume")+"\t\t resume previously interrupted operations")
print_info(" \t\t"+red("--empty")+"\t\t\t set all dependencies as unsatisfied")
print_info(" \t\t"+red("--deep")+"\t\t\t analyze dependencies deeply")
print_info(" \t\t"+red("--verbose")+"\t\t show more details about what's going on")
@@ -66,6 +68,7 @@ def print_help():
print_info(" \t"+blue("remove")+brown("\t\t remove one or more packages"))
print_info(" \t\t"+red("--deep")+"\t\t\t also pull unused dependencies where depends list is empty")
print_info(" \t\t"+red("--configfiles")+"\t\t also remove configuration files")
print_info(" \t\t"+red("--resume")+"\t\t resume previously interrupted operations")
print_info(" \t"+blue("deptest")+brown("\t\t look for unsatisfied dependencies"))
print_info(" \t\t"+red("--quiet")+"\t\t\t show less details (useful for scripting)")
print_info(" \t\t"+red("--ask")+"\t\t\t ask before making any changes")
+27 -104
View File
@@ -21,17 +21,13 @@
'''
from sys import path, getfilesystemencoding
path.append('../libraries')
path.append('../client')
path.append('/usr/lib/entropy/libraries')
import os
import shutil
import stat
from entropyConstants import *
from clientConstants import *
from outputTools import *
from remoteTools import downloadData
from entropyTools import compareMd5, bytesIntoHuman, askquestion, getRandomNumber, dep_getkey, entropyCompareVersions, filterDuplicatedEntries, extractDuplicatedEntries, uncompressTarBz2, extractXpak, applicationLockCheck, countdown, isRoot, spliturl, remove_tag, dep_striptag, md5sum, allocateMaskedFile, istextfile, isnumber, extractEdb, getNewerVersion, getNewerVersionTag, unpackXpak, lifobuffer, writeNewBranch
from entropyTools import compareMd5, bytesIntoHuman, askquestion, getRandomNumber, dep_getkey, entropyCompareVersions, filterDuplicatedEntries, extractDuplicatedEntries, uncompressTarBz2, extractXpak, applicationLockCheck, countdown, isRoot, spliturl, remove_tag, dep_striptag, md5sum, allocateMaskedFile, istextfile, isnumber, extractEdb, getNewerVersion, getNewerVersionTag, unpackXpak, lifobuffer
from databaseTools import openRepositoryDatabase, openClientDatabase, openGenericDatabase, fetchRepositoryIfNotAvailable, listAllAvailableBranches
import triggerTools
import confTools
@@ -896,6 +892,7 @@ def removePackage(infoDict):
atom = infoDict['removeatom']
content = infoDict['removecontent']
removeidpackage = infoDict['removeidpackage']
clientDbconn = openClientDatabase()
equoLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_NORMAL,"Removing package: "+str(atom))
@@ -903,15 +900,6 @@ def removePackage(infoDict):
generateDependsTreeCache.clear()
dumpTools.dumpobj(etpCache['generateDependsTree'],generateDependsTreeCache)
# load content cache if found empty
if etpConst['collisionprotect'] > 0:
if (not contentCache):
clientDbconn = openClientDatabase()
xlist = clientDbconn.listAllFiles(clean = True)
for x in xlist:
contentCache[x] = 1
clientDbconn.closeDB()
# remove from database
if removeidpackage != -1:
print_info(red(" ## ")+blue("Removing from database: ")+red(infoDict['removeatom']))
@@ -927,20 +915,17 @@ def removePackage(infoDict):
protect = etpConst['dbconfigprotect']
mask = etpConst['dbconfigprotectmask']
# remove files from system
directories = set()
for file in content:
# collision check
if etpConst['collisionprotect'] > 0:
if file in contentCache:
if clientDbconn.isFileAvailable(file) and os.path.isfile(file): # in this way we filter out directories
print_warning(darkred(" ## ")+red("Collision found during remove for ")+file+red(" - cannot overwrite"))
equoLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_NORMAL,"Collision found during remove for "+file+" - cannot overwrite")
content.remove(file)
continue
try:
del contentCache[file]
except:
pass
protected = False
if (not infoDict['removeconfig']) and (not infoDict['diffremoval']):
@@ -965,7 +950,7 @@ def removePackage(infoDict):
pass # some filenames are buggy encoded
if (protected):
equoLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_VERBOSE,"[remove] Protecting config file: "+file)
equoLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_VERBOSE,"[remove] Protecting config file: "+file)
print_warning(darkred(" ## ")+red("[remove] Protecting config file: ")+file)
else:
try:
@@ -1029,6 +1014,7 @@ def removePackage(infoDict):
if not taint:
break
clientDbconn.closeDB()
return 0
@@ -1038,7 +1024,7 @@ def removePackage(infoDict):
@output: 0 = all fine, >0 = error!
'''
def installPackage(infoDict):
clientDbconn = openClientDatabase()
package = infoDict['download']
@@ -1048,13 +1034,6 @@ def installPackage(infoDict):
equoLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_NORMAL,"Installing package: "+str(infoDict['atom']))
# load content cache if found empty
if etpConst['collisionprotect'] > 0:
if (not contentCache):
xlist = clientDbconn.listAllFiles(clean = True)
for x in xlist:
contentCache[x] = 1
# unpack and install
if infoDict['repository'].endswith(".tbz2"):
pkgpath = etpRepositories[infoDict['repository']]['pkgpath']
@@ -1065,17 +1044,17 @@ def installPackage(infoDict):
shutil.rmtree(unpackDir)
imageDir = unpackDir+"/image"
os.makedirs(imageDir)
rc = uncompressTarBz2(pkgpath,imageDir)
if (rc != 0):
return rc
if not os.path.isdir(imageDir):
return 2
# load CONFIG_PROTECT and its mask
protect = etpRepositories[infoDict['repository']]['configprotect']
mask = etpRepositories[infoDict['repository']]['configprotectmask']
packageContent = []
# setup imageDir properly
imageDir = imageDir.encode(getfilesystemencoding())
@@ -1121,9 +1100,9 @@ def installPackage(infoDict):
tofile = fromfile[len(imageDir):]
if etpConst['collisionprotect'] > 1:
if tofile in contentCache:
print_warning(darkred(" ## ")+red("Collision found during install for ")+file.encode(getfilesystemencoding())+" - cannot overwrite")
equoLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_NORMAL,"WARNING!!! Collision found during install for "+file.encode(getfilesystemencoding())+" - cannot overwrite")
if clientDbconn.isFileAvailable(tofile):
print_warning(darkred(" ## ")+red("Collision found during install for ")+tofile+" - cannot overwrite")
equoLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_NORMAL,"WARNING!!! Collision found during install for "+tofile+" - cannot overwrite")
equoLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_NORMAL,"[collision] Protecting config file: "+tofile)
print_warning(darkred(" ## ")+red("[collision] Protecting config file: ")+tofile)
continue
@@ -1142,15 +1121,7 @@ def installPackage(infoDict):
protected = False
break
if os.access(tofile,os.F_OK):
try:
if not protected: os.remove(tofile)
except:
if not protected:
rc = os.system("rm -f "+tofile)
if (rc != 0):
return 3
else:
if not os.path.lexists(tofile):
protected = False # file doesn't exist
# check if it's a text file
@@ -1159,21 +1130,14 @@ def installPackage(infoDict):
else:
protected = False # it's not a file
# check md5
if (protected) and os.path.isfile(tofile) and os.path.isfile(fromfile):
mymd5 = md5sum(fromfile)
sysmd5 = md5sum(tofile)
if mymd5 == sysmd5:
protected = False # files are the same
else:
protected = False # a broken symlink inside our image dir
# request new tofile then
if (protected):
equoLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_NORMAL,"Protecting config file: "+tofile)
print_warning(darkred(" ## ")+red("Protecting config file: ")+tofile)
tofile = allocateMaskedFile(tofile)
tofile, prot_status = allocateMaskedFile(tofile, fromfile)
if not prot_status:
protected = False
else:
equoLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_NORMAL,"Protecting config file: "+tofile)
print_warning(darkred(" ## ")+red("Protecting config file: ")+tofile)
# -- CONFIGURATION FILE PROTECTION --
@@ -1223,17 +1187,14 @@ def installPackage(infoDict):
clientDbconn.closeDB()
rc = 0
if (etpConst['gentoo-compat']):
equoLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_NORMAL,"Installing new Gentoo database entry: "+str(infoDict['atom']))
rc = installPackageIntoGentooDatabase(infoDict,pkgpath, newidpackage = newidpackage)
if (rc >= 0):
shutil.rmtree(unpackDir,True)
return rc
# remove unpack dir
shutil.rmtree(unpackDir,True)
return 0
return rc
'''
@description: remove package entry from Gentoo database
@@ -1397,41 +1358,18 @@ def installPackageIntoDatabase(idpackage, repository):
# fetch info
dbconn = openRepositoryDatabase(repository)
data = dbconn.getPackageData(idpackage)
# get current revision
rev = dbconn.retrieveRevision(idpackage)
branch = dbconn.retrieveBranch(idpackage)
newcontent = dbconn.retrieveContent(idpackage)
dbconn.closeDB()
# open client db
clientDbconn = openClientDatabase()
# load content cache
if etpConst['collisionprotect'] > 0:
if (not contentCache):
xlist = clientDbconn.listAllFiles(clean = True)
for x in xlist:
contentCache[x] = 1
# sync contentCache before install
for x in newcontent:
contentCache[x] = 1
dbconn.closeDB()
idpk, rev, x, status = clientDbconn.handlePackage(etpData = data, forcedRevision = rev)
idpk, rev, x, status = clientDbconn.handlePackage(etpData = data, forcedRevision = data['revision'])
del x
if (not status):
clientDbconn.closeDB()
print "DEBUG!!! THIS SHOULD NOT NEVER HAPPEN. Package "+str(idpk)+" has not been inserted, status: "+str(status)
idpk = -1 # it hasn't been insterted ? why??
else: # all fine
# regenerate contentCache
if etpConst['collisionprotect'] > 0:
xlist = clientDbconn.listAllFiles(clean = True)
contentCache.clear()
for x in xlist:
contentCache[x] = 1
# add idpk to the installedtable
clientDbconn.removePackageFromInstalledTable(idpk)
clientDbconn.addPackageToInstalledTable(idpk,repository)
@@ -1461,22 +1399,7 @@ def installPackageIntoDatabase(idpackage, repository):
def removePackageFromDatabase(idpackage):
clientDbconn = openClientDatabase()
# load content cache
if etpConst['collisionprotect'] > 0:
if (not contentCache):
xlist = clientDbconn.listAllFiles(clean = True)
for x in xlist:
contentCache[x] = 1
# sync contentCache before removal
content = clientDbconn.retrieveContent(idpackage)
for x in content:
try:
del contentCache[x]
except:
pass
clientDbconn.removePackage(idpackage)
clientDbconn.closeDB()
return 0
+3 -3
View File
@@ -125,7 +125,7 @@ def postinstall(pkgdata):
functions.add('createkernelsym')
for path in ldpaths:
if x.startswith(path) and (x.find(".so") != -1):
functions.add('ldconfig')
functions.add('run_ldconfig')
#if x.startswith("/etc/init.d/"): do it externally
# functions.add('initadd')
@@ -213,7 +213,7 @@ def postremove(pkgdata):
functions.add('cleanpy')
for path in ldpaths:
if x.startswith(path) and (x.find(".so") != -1):
functions.add('ldconfig')
functions.add('run_ldconfig')
return functions
@@ -531,7 +531,7 @@ def createkernelsym(pkgdata):
os.symlink(todir,"/usr/src/linux")
break
def ldconfig(pkgdata):
def run_ldconfig(pkgdata):
equoLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_NORMAL,"[POST] Running ldconfig")
print_info(red(" ##")+brown(" Regenerating /etc/ld.so.cache"))
os.system("ldconfig &> /dev/null")
+669 -553
View File
File diff suppressed because it is too large Load Diff
+21 -6
View File
@@ -56,7 +56,7 @@ def openRepositoryDatabase(repositoryName, xcache = True):
raise Exception, "openRepositoryDatabase: cannot sync repository "+repositoryName
conn = etpDatabase(readOnly = True, dbFile = dbfile, clientDatabase = True, dbname = 'repo_'+repositoryName, xcache = xcache)
# initialize CONFIG_PROTECT
if (not etpRepositories[repositoryName]['configprotect']) or (not etpRepositories[repositoryName]['configprotectmask']):
if (etpRepositories[repositoryName]['configprotect'] == None) or (etpRepositories[repositoryName]['configprotectmask'] == None):
etpRepositories[repositoryName]['configprotect'] = conn.listConfigProtectDirectories()
etpRepositories[repositoryName]['configprotectmask'] = conn.listConfigProtectDirectories(mask = True)
etpRepositories[repositoryName]['configprotect'] += [x for x in etpConst['configprotect'] if x not in etpRepositories[repositoryName]['configprotect']]
@@ -1564,11 +1564,11 @@ class etpDatabase:
return data
def fetchall2set(self, item):
content = set()
mycontent = set()
for x in item:
for y in x:
content.add(y)
return content
mycontent.add(y)
return mycontent
def fetchall2list(self, item):
content = []
@@ -2000,6 +2000,8 @@ class etpDatabase:
def retrieveContent(self, idpackage, extended = False):
dbLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_VERBOSE,"retrieveContent: retrieving Content for package ID "+str(idpackage))
self.createContentIndex() # FIXME: remove this with 1.0
extstring = ''
if extended:
extstring = ",type"
@@ -2164,6 +2166,17 @@ class etpDatabase:
dbLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_VERBOSE,"isProtectAvailable: "+protect+" available.")
return result[0]
def isFileAvailable(self,file):
dbLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_VERBOSE,"isFileAvailable: called.")
self.createContentIndex() # FIXME: remove this with 1.0
self.cursor.execute('SELECT idpackage FROM content WHERE file = "'+file+'"')
result = self.cursor.fetchone()
if not result:
dbLog.log(ETP_LOGPRI_WARNING,ETP_LOGLEVEL_NORMAL,"isFileAvailable: "+file+" not available.")
return False
dbLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_VERBOSE,"isFileAvailable: "+file+" available.")
return True
def isSourceAvailable(self,source):
dbLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_VERBOSE,"isSourceAvailable: called.")
self.cursor.execute('SELECT idsource FROM sourcesreference WHERE source = "'+source+'"')
@@ -2574,8 +2587,7 @@ class etpDatabase:
dbLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_VERBOSE,"listAllFiles: called.")
self.cursor.execute('SELECT file FROM content')
if clean:
x = self.fetchall2set(self.cursor.fetchall())
return x
return self.fetchall2set(self.cursor.fetchall())
else:
return self.fetchall2list(self.cursor.fetchall())
@@ -2763,6 +2775,9 @@ class etpDatabase:
self.cursor.execute('CREATE TABLE counters ( counter INTEGER PRIMARY KEY, idpackage INTEGER );')
self.commitChanges()
def createContentIndex(self):
self.cursor.execute('CREATE INDEX IF NOT EXISTS contentindex ON content ( file )')
def regenerateCountersTable(self, output = False):
self.createCountersTable()
# assign a counter to an idpackage
+35 -19
View File
@@ -19,38 +19,54 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
'''
import sys
import commands
sys.path.append('../libraries')
from xml.dom import minidom
from entropyConstants import *
curname = ''
'''
@description: dump object to file
@input: name of the object, object
@output: status code
'''
def dumpobj(name,object):
doc = minidom.Document()
structure = doc.createElement("structure")
doc.appendChild(structure)
data = doc.createElement("data")
structure.appendChild(data)
text = doc.createTextNode(unicode(object))
data.appendChild(text)
# etpConst['dumpstoragedir']
curname = name
try:
if not os.path.isdir(etpConst['dumpstoragedir']):
os.makedirs(etpConst['dumpstoragedir'])
f = open(etpConst['dumpstoragedir']+"/"+name+".dmp","w") #FIXME add check
f.writelines(doc.toprettyxml(indent=" "))
f.flush()
f.close()
except:
raise IOError,"can't write to file"
doc = minidom.Document()
structure = doc.createElement("structure")
doc.appendChild(structure)
data = doc.createElement("data")
structure.appendChild(data)
text = doc.createTextNode(unicode(object))
data.appendChild(text)
# etpConst['dumpstoragedir']
try:
if not os.path.isdir(etpConst['dumpstoragedir']):
os.makedirs(etpConst['dumpstoragedir'])
f = open(etpConst['dumpstoragedir']+"/"+name+".dmp","w") #FIXME add check
f.writelines(doc.toprettyxml(indent=" "))
f.flush()
f.close()
except:
raise IOError,"can't write to file "+name
except KeyboardInterrupt:
import signal
signal.signal(signal.SIGTERM, removeobj)
signal.signal(signal.SIGQUIT, removeobj)
signal.signal(signal.SIGINT, removeobj)
signal.signal(signal.SIGHUP, removeobj)
dumpobj(name,object)
sys.exit(1)
def removeobj():
if curname:
try:
os.remove(etpConst['dumpstoragedir']+"/"+curname+".dmp")
except:
pass
'''
@description: load object from a file
@input: name of the object
+7 -5
View File
@@ -281,6 +281,8 @@ CREATE TABLE neededreference (
library VARCHAR
);
CREATE INDEX contentindex ON content ( file );
"""
# Entropy directories specifications
@@ -437,6 +439,9 @@ etpCache = {
'dbInfo': 'info_', # used by the database controller as prefix to the cache files belonging to etpDatabase class (info retrival)
'atomMatch': 'atomMatchCache', # used to store info about repository dependencies solving
'generateDependsTree': 'generateDependsTreeCache', # used to store info about removal dependencies
'install': 'resume_install', # resume cache (install)
'remove': 'resume_remove', # resume cache (remove)
'world': 'resume_world', # resume cache (world)
}
# byte sizes of disk caches
@@ -467,15 +472,12 @@ global atomMatchCache
atomMatchCache = {}
global atomClientMatchCache
atomClientMatchCache = {}
global contentCache
contentCache = {}
global generateDependsTreeCache
generateDependsTreeCache = {}
def const_resetCache():
dbCacheStore.clear()
atomMatchCache.clear()
atomClientMatchCache.clear()
contentCache.clear()
generateDependsTreeCache.clear()
# handle Entropy Version
@@ -628,8 +630,8 @@ if os.path.isfile(etpConst['repositoriesconf']):
etpRepositories[reponame]['dbcformat'] = dbformat
etpRepositories[reponame]['database'] = repodatabase+"/"+etpConst['product']+"/database/"+etpConst['currentarch']
# initialize CONFIG_PROTECT - will be filled the first time the db will be opened
etpRepositories[reponame]['configprotect'] = set()
etpRepositories[reponame]['configprotectmask'] = set()
etpRepositories[reponame]['configprotect'] = None
etpRepositories[reponame]['configprotectmask'] = None
elif (line.find("branch|") != -1) and (not line.startswith("#")) and (len(line.split("|")) == 2):
branch = line.split("|")[1]
etpConst['branch'] = branch
+60 -10
View File
@@ -26,7 +26,7 @@ from entropyConstants import *
import os
import re
from sys import exit, stdout, getfilesystemencoding
import threading, time
import threading, time, tarfile
# Instantiate the databaseStatus:
import databaseTools
@@ -333,10 +333,19 @@ def md5string(string):
return m.hexdigest()
# used by equo, this function retrieves the new safe Gentoo-aware file path
def allocateMaskedFile(file):
def allocateMaskedFile(file, fromfile):
# check if file and tofile are equal
if os.path.isfile(file) and os.path.isfile(fromfile):
old = md5sum(fromfile)
new = md5sum(file)
if old == new:
return file, False
counter = -1
newfile = ""
previousfile = ""
while 1:
counter += 1
txtcounter = str(counter)
@@ -354,13 +363,22 @@ def allocateMaskedFile(file):
if not newfile:
newfile = os.path.dirname(file)+"/"+"._cfg0000_"+os.path.basename(file)
else:
if os.path.exists(previousfile):
if os.path.exists(previousfile):
# compare fromfile with previousfile
new = md5sum(fromfile)
old = md5sum(previousfile)
if new == old:
return previousfile, False
# compare old and new, if they match, suggest previousfile directly
new = md5sum(file)
old = md5sum(previousfile)
if (new == old):
newfile = previousfile
return newfile
return previousfile, False
return newfile, True
def extractElog(file):
@@ -1041,12 +1059,45 @@ def compressTarBz2(storepath,pathtocompress):
# tar.bz2 uncompress function...
def uncompressTarBz2(filepath, extractPath = None):
entropyLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_VERBOSE,"uncompressTarBz2: called. ")
entropyLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_VERBOSE,"uncompressTarBz2: called.")
if extractPath is None:
extractPath = os.path.dirname(filepath)
cmd = "tar xjf "+filepath+" -C "+extractPath
rc = spawnCommand(cmd, "&> /dev/null")
return rc
tar = tarfile.open(filepath,"r:bz2")
directories = []
for tarinfo in tar:
if tarinfo.isdir():
# Extract directory with a safe mode, so that
# all files below can be extracted as well.
try:
os.makedirs(os.path.join(extractPath, tarinfo.name), 0777)
except EnvironmentError:
pass
directories.append(tarinfo)
else:
tar.extract(tarinfo, extractPath)
# Reverse sort directories.
directories.sort(lambda a, b: cmp(a.name, b.name))
directories.reverse()
origpath = extractPath
# Set correct owner, mtime and filemode on directories.
for tarinfo in directories:
extractPath = os.path.join(extractPath, tarinfo.name)
try:
tar.chown(tarinfo, extractPath)
tar.utime(tarinfo, extractPath)
tar.chmod(tarinfo, extractPath)
except tarfile.ExtractError, e:
if tar.errorlevel > 1:
raise
tar.close()
if os.listdir(origpath):
return 0
else:
return -1
def bytesIntoHuman(bytes):
size = str(round(float(bytes)/1024,1))
@@ -1230,7 +1281,6 @@ def writeNewBranch(branch):
def quickpkg(pkgdata,dirpath):
entropyLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_VERBOSE,"quickpkg: called -> "+str(pkgdata)+" | dirpath: "+dirpath)
import tarfile
import stat
import databaseTools