diff --git a/TODO b/TODO index ce8b41a19..3dc37528d 100644 --- a/TODO +++ b/TODO @@ -2,8 +2,9 @@ TODO list: CLIENT: - add external triggerable hooks support - include more triggers - - allow .tbz2 separate install - finalize smartapps tool + - use depgraph generation function to generate dependencies + - installPackages should pull conflicts depends too Project Status: diff --git a/client/equo b/client/equo index b68978594..73c80270e 100644 --- a/client/equo +++ b/client/equo @@ -40,13 +40,15 @@ def print_help(): print_info(" \t"+blue("status")+brown("\t\t show respositories status")) print_info(" \t"+blue("search")+brown("\t\t search a package trough repositories")) + print_info(" \t"+blue("world")+brown("\t\t update system with the latest available packages")) print_info(" \t\t"+red("--ask")+"\t\t\t ask before making any changes") print_info(" \t\t"+red("--fetch")+"\t\t\t just download packages without doing the install") print_info(" \t\t"+red("--pretend")+"\t\t just show what would be done") 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"+blue("install")+brown("\t\t install one or more packages")) + + print_info(" \t"+blue("install")+brown("\t\t install one or more packages or .tbz2")) print_info(" \t\t"+red("--ask")+"\t\t\t ask before making any changes") 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") @@ -55,6 +57,7 @@ def print_help(): 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") print_info(" \t\t"+red("--configfiles")+"\t\t also remove old configuration files [use with care]") + 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") diff --git a/client/equoTools.py b/client/equoTools.py index 99dc71fce..4a3324641 100644 --- a/client/equoTools.py +++ b/client/equoTools.py @@ -29,8 +29,8 @@ from entropyConstants import * from clientConstants import * from outputTools import * from remoteTools import downloadData, getOnlineContent -from entropyTools import unpackGzip, unpackBzip2, compareMd5, bytesIntoHuman, askquestion, getRandomNumber, isjustname, dep_getkey, compareVersions as entropyCompareVersions, filterDuplicatedEntries, extractDuplicatedEntries, uncompressTarBz2, extractXpak, applicationLockCheck, countdown, isRoot, spliturl, remove_tag, dep_striptag, md5sum, allocateMaskedFile, istextfile, isnumber -from databaseTools import etpDatabase, openRepositoryDatabase, openClientDatabase +from entropyTools import unpackGzip, unpackBzip2, compareMd5, bytesIntoHuman, askquestion, getRandomNumber, isjustname, dep_getkey, compareVersions as entropyCompareVersions, filterDuplicatedEntries, extractDuplicatedEntries, uncompressTarBz2, extractXpak, applicationLockCheck, countdown, isRoot, spliturl, remove_tag, dep_striptag, md5sum, allocateMaskedFile, istextfile, isnumber, extractEdb +from databaseTools import etpDatabase, openRepositoryDatabase, openClientDatabase, openGenericDatabase import triggerTools import confTools import dumpTools @@ -373,7 +373,7 @@ def fetchRepositoryIfNotAvailable(reponame): @ exit errors: -1 => repository cannot be fetched online ''' -def atomMatch(atom, caseSentitive = True, matchSlot = None, matchBranches = (), xcache = True): # no one seems to use matchBranches :D +def atomMatch(atom, caseSentitive = True, matchSlot = None, matchBranches = (), xcache = True): if xcache: cached = atomMatchCache.get(atom) @@ -1314,7 +1314,10 @@ def installPackage(infoDict): contentCache[x] = 1 # unpack and install - pkgpath = etpConst['entropyworkdir']+"/"+package + if infoDict['repository'].endswith(".tbz2"): + pkgpath = etpRepositories[infoDict['repository']]['pkgpath'] + else: + pkgpath = etpConst['entropyworkdir']+"/"+package unpackDir = etpConst['entropyunpackdir']+"/"+package if os.path.isdir(unpackDir): os.system("rm -rf "+unpackDir) @@ -1732,6 +1735,7 @@ def package(options): equoRequestReplay = False rc = 0 _myopts = [] + mytbz2paths = [] for opt in myopts: if (opt == "--ask"): equoRequestAsk = True @@ -1754,7 +1758,10 @@ def package(options): elif (opt == "--replay"): equoRequestReplay = True else: - _myopts.append(opt) + if opt[-5:] == ".tbz2" and os.access(opt,os.R_OK): + mytbz2paths.append(opt) + else: + _myopts.append(opt) myopts = _myopts if (options[0] == "deptest"): @@ -1762,9 +1769,9 @@ def package(options): rc, garbage = dependenciesTest(quiet = equoRequestQuiet, ask = equoRequestAsk, pretend = equoRequestPretend) elif (options[0] == "install"): - if len(myopts) > 0: + if (myopts) or (mytbz2paths): loadCaches() - rc, status = installPackages(myopts, ask = equoRequestAsk, pretend = equoRequestPretend, verbose = equoRequestVerbose, deps = equoRequestDeps, emptydeps = equoRequestEmptyDeps, onlyfetch = equoRequestOnlyFetch, deepdeps = equoRequestDeep, configFiles = equoRequestConfigFiles) + rc, status = installPackages(myopts, ask = equoRequestAsk, pretend = equoRequestPretend, verbose = equoRequestVerbose, deps = equoRequestDeps, emptydeps = equoRequestEmptyDeps, onlyfetch = equoRequestOnlyFetch, deepdeps = equoRequestDeep, configFiles = equoRequestConfigFiles, tbz2 = mytbz2paths) else: print_error(red(" Nothing to do.")) rc = 127 @@ -2101,7 +2108,7 @@ def worldUpdate(ask = False, pretend = False, verbose = False, onlyfetch = False clientDbconn.closeDB() return 0,0 -def installPackages(packages = [], atomsdata = [], ask = False, pretend = False, verbose = False, deps = True, emptydeps = False, onlyfetch = False, deepdeps = False, configFiles = False): +def installPackages(packages = [], atomsdata = [], ask = False, pretend = False, verbose = False, deps = True, emptydeps = False, onlyfetch = False, deepdeps = False, configFiles = False, tbz2 = []): # check if I am root if (not isRoot()) and (not pretend): @@ -2114,6 +2121,28 @@ def installPackages(packages = [], atomsdata = [], ask = False, pretend = False, foundAtoms = [] for package in packages: foundAtoms.append([package,atomMatch(package)]) + if tbz2: + for pkg in tbz2: + # create a repository for each database + basefile = os.path.basename(pkg) + if os.path.isdir(etpConst['entropyunpackdir']+"/"+basefile[:-5]): + shutil.rmtree(etpConst['entropyunpackdir']+"/"+basefile[:-5]) + os.makedirs(etpConst['entropyunpackdir']+"/"+basefile[:-5]) + dbfile = extractEdb(pkg,dbpath = etpConst['entropyunpackdir']+"/"+basefile[:-5]+"/packages.db") + # add dbfile + etpRepositories[basefile] = {} + etpRepositories[basefile]['description'] = "Dynamic database from "+basefile + etpRepositories[basefile]['packages'] = [] + etpRepositories[basefile]['dbpath'] = os.path.dirname(dbfile) + etpRepositories[basefile]['pkgpath'] = os.path.realpath(pkg) # extra info added + etpRepositories[basefile]['configprotect'] = set() + etpRepositories[basefile]['configprotectmask'] = set() + mydbconn = openGenericDatabase(dbfile) + # read all idpackages + myidpackages = mydbconn.listAllIdpackages() # all branches admitted from external files + for myidpackage in myidpackages: + foundAtoms.append([pkg,(int(myidpackage),basefile)]) + mydbconn.closeDB() # filter packages not found _foundAtoms = [] @@ -2431,9 +2460,10 @@ def installPackages(packages = [], atomsdata = [], ask = False, pretend = False, steps = [] # download - if (actionQueue[pkgatom]['fetch'] < 0): - steps.append("fetch") - steps.append("checksum") + if not repository.endswith(".tbz2"): + if (actionQueue[pkgatom]['fetch'] < 0): + steps.append("fetch") + steps.append("checksum") # differential remove list if (actionQueue[pkgatom]['removeidpackage'] != -1): diff --git a/libraries/databaseTools.py b/libraries/databaseTools.py index c764e10d8..c56222c15 100644 --- a/libraries/databaseTools.py +++ b/libraries/databaseTools.py @@ -523,12 +523,20 @@ def openClientDatabase(xcache = True): ''' @description: open the entropy server database and returns the pointer. This function must be used only by reagent or activator - @output: database pointer or, -1 if error + @output: database pointer ''' def openServerDatabase(readOnly = True, noUpload = True): conn = etpDatabase(readOnly = readOnly, dbFile = etpConst['etpdatabasefilepath'], noUpload = noUpload) return conn +''' + @description: open a generic client database and returns the pointer. + @output: database pointer +''' +def openGenericDatabase(dbfile): + conn = etpDatabase(readOnly = False, dbFile = dbfile, clientDatabase = True, dbname = "generic", xcache = False) + return conn + # this class simply describes the current database status # FIXME: need a rewrite? simply using dicts, perhaps? class databaseStatus: @@ -2781,11 +2789,10 @@ class etpDatabase: self.cursor.execute('SELECT atom,idpackage FROM baseinfo WHERE name = "'+name+'" and version = "'+version+'" and idcategory = '+str(idcat)+branchstring) else: self.cursor.execute('SELECT atom,idpackage FROM baseinfo WHERE LOWER(name) = "'+name.lower()+'" and version = "'+version+'" and idcategory = '+str(idcat)+branchstring) - - if (self.xcache): - self.storeSearchCache((name,version,category,branch,sensitive),'searchPackagesByNameAndVersionAndCategory',results) + results = self.cursor.fetchall() - + if (self.xcache): + self.storeSearchCache((name,version,category,branch,sensitive),'searchPackagesByNameAndVersionAndCategory',results) return results def listAllPackages(self): diff --git a/libraries/entropyTools.py b/libraries/entropyTools.py index d27176c47..e07c7d434 100644 --- a/libraries/entropyTools.py +++ b/libraries/entropyTools.py @@ -211,10 +211,11 @@ def aggregateEdb(tbz2file,dbfile): f.flush() f.close() -def extractEdb(tbz2file): +def extractEdb(tbz2file, dbpath = None): entropyLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_VERBOSE,"extractEdb: called -> "+tbz2file) old = open(tbz2file,"rb") - dbpath = tbz2file[:-5]+".db" + if not dbpath: + dbpath = tbz2file[:-5]+".db" db = open(dbpath,"wb") # position old to the end @@ -241,6 +242,7 @@ def extractEdb(tbz2file): db.flush() db.close() old.close() + return dbpath # This function creates the .md5 file related to the given package file