Files
entropy/libraries/reagentTools.py
(no author) 1ceb8beae0 - 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
2007-10-10 23:39:34 +00:00

1049 lines
35 KiB
Python

#!/usr/bin/python
'''
# DESCRIPTION:
# generic tools for reagent application
Copyright (C) 2007 Fabio Erculiani
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
'''
# Never do "import portage" here, please use entropyTools binding
# EXIT STATUSES: 500-599
from entropyConstants import *
from serverConstants import *
from entropyTools import *
import commands
import re
import sys
import os
import string
from portageTools import synthetizeRoughDependencies, getThirdPartyMirrors, getPackagesInSystem, getConfigProtectAndMask
# Logging initialization
import logTools
reagentLog = logTools.LogFile(level=etpConst['reagentloglevel'],filename = etpConst['reagentlogfile'], header = "[Reagent]")
# reagentLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_VERBOSE,"testFunction: example. ")
def generator(package, dbconnection = None, enzymeRequestBranch = etpConst['branch']):
reagentLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_VERBOSE,"generator: called -> Package: "+str(package)+" | dbconnection: "+str(dbconnection))
# check if the package provided is valid
validFile = False
if os.path.isfile(package) and package.endswith(".tbz2"):
validFile = True
if (not validFile):
print_warning(package+" does not exist !")
packagename = os.path.basename(package)
print_info(yellow(" * ")+red("Processing: ")+bold(packagename)+red(", please wait..."))
etpData = extractPkgData(package, enzymeRequestBranch)
if dbconnection is None:
dbconn = databaseTools.etpDatabase(readOnly = False, noUpload = True)
else:
dbconn = dbconnection
idpk, revision, etpDataUpdated, accepted = dbconn.handlePackage(etpData)
# add package info to our official repository etpConst['officialrepositoryname']
if (accepted):
dbconn.removePackageFromInstalledTable(idpk)
dbconn.addPackageToInstalledTable(idpk,etpConst['officialrepositoryname'])
# return back also the new possible package filename, so that we can make decisions on that
newFileName = os.path.basename(etpDataUpdated['download'])
if dbconnection is None:
dbconn.commitChanges()
dbconn.closeDB()
if (accepted) and (revision != 0):
reagentLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_VERBOSE,"generator: entry for "+str(packagename)+" has been updated to revision: "+str(revision))
print_info(green(" * ")+red("Package ")+bold(packagename)+red(" entry has been updated. Revision: ")+bold(str(revision)))
return True, newFileName, idpk
elif (accepted) and (revision == 0):
reagentLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_VERBOSE,"generator: entry for "+str(packagename)+" newly created or version bumped.")
print_info(green(" * ")+red("Package ")+bold(packagename)+red(" entry newly created."))
return True, newFileName, idpk
else:
reagentLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_VERBOSE,"generator: entry for "+str(packagename)+" kept intact, no updates needed.")
print_info(green(" * ")+red("Package ")+bold(packagename)+red(" does not need to be updated. Current revision: ")+bold(str(revision)))
return False, newFileName, idpk
# This tool is used by Entropy after enzyme, it simply parses the content of etpConst['packagesstoredir']
def update(options):
reagentLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_VERBOSE,"update: called -> options: "+str(options))
# differential checking
# collect differences between the packages in the database and the ones on the system
reagentRequestSeekStore = False
_options = []
for opt in options:
if opt.startswith("--seekstore"):
reagentRequestSeekStore = True
else:
_options.append(opt)
options = _options
if (not reagentRequestSeekStore):
print_info(yellow(" * ")+red("Scanning the database for differences..."))
dbconn = databaseTools.etpDatabase(readOnly = True, noUpload = True)
from portageTools import getInstalledPackagesCounters, quickpkg, getPackageSlot
installedPackages = getInstalledPackagesCounters()
installedCounters = {}
databasePackages = dbconn.listAllPackages()
toBeAdded = []
toBeRemoved = []
# fill lists
# packages to be added
for x in installedPackages[0]:
installedCounters[x[1]] = 1
counter = dbconn.isCounterAvailable(x[1])
if (not counter):
toBeAdded.append(x)
# packages to be removed from the database
databaseCounters = dbconn.listAllCounters()
for x in databaseCounters:
match = installedCounters.get(x[0], None)
#print match
if (not match):
# check if the package is in toBeAdded
if (toBeAdded):
atomkey = dep_getkey(dbconn.retrieveAtom(x[1]))
atomslot = dbconn.retrieveSlot(x[1])
add = True
for pkgdata in toBeAdded:
addslot = getPackageSlot(pkgdata[0])
addkey = dep_getkey(pkgdata[0])
# workaround for ebuilds not having slot
if addslot == None:
addslot = ''
if (atomkey == addkey) and (atomslot == addslot):
# do not add to toBeRemoved
add = False
break
if add:
toBeRemoved.append(x[1])
else:
toBeRemoved.append(x[1])
if (not toBeRemoved) and (not toBeAdded):
print_info(yellow(" * ")+red("Nothing to do, check later."))
# then exit gracefully
sys.exit(0)
if (toBeRemoved):
print_info(yellow(" @@ ")+blue("These are the packages that would be removed from the database:"))
for x in toBeRemoved:
atom = dbconn.retrieveAtom(x)
print_info(yellow(" # ")+red(atom))
rc = askquestion(">> Would you like to remove them now ?")
if rc == "Yes":
rwdbconn = databaseTools.etpDatabase(readOnly = False, noUpload = True)
for x in toBeRemoved:
atom = rwdbconn.retrieveAtom(x)
print_info(yellow(" @@ ")+blue("Removing from database: ")+red(atom), back = True)
rwdbconn.removePackage(x)
rwdbconn.closeDB()
print_info(yellow(" @@ ")+blue("Database removal complete."))
if (toBeAdded):
print_info(yellow(" @@ ")+blue("These are the packages that would be added/updated to the add list:"))
for x in toBeAdded:
print_info(yellow(" # ")+red(x[0]))
rc = askquestion(">> Would you like to packetize them now ?")
if rc == "No":
sys.exit(0)
# package them
print_info(yellow(" @@ ")+blue("Compressing packages..."))
for x in toBeAdded:
print_info(yellow(" # ")+red(x[0]+"..."))
rc = quickpkg(x[0],etpConst['packagesstoredir'])
if (rc is None):
reagentLog.log(ETP_LOGPRI_ERROR,ETP_LOGLEVEL_NORMAL,"update: "+str(dep)+" -> quickpkg error. Cannot continue.")
print_error(red(" *")+" quickpkg error for "+red(dep))
print_error(red(" ***")+" Fatal error, cannot continue")
sys.exit(251)
dbconn.closeDB()
enzymeRequestBranch = etpConst['branch']
#_atoms = []
for i in options:
if ( i == "--branch=" and len(i.split("=")) == 2 ):
mybranch = i.split("=")[1]
if (mybranch):
enzymeRequestBranch = mybranch
tbz2files = os.listdir(etpConst['packagesstoredir'])
totalCounter = 0
# counting the number of files
for i in tbz2files:
totalCounter += 1
if (totalCounter == 0):
print_info(yellow(" * ")+red("Nothing to do, check later."))
# then exit gracefully
sys.exit(0)
# open db connection
dbconn = databaseTools.etpDatabase(readOnly = False, noUpload = True)
counter = 0
etpCreated = 0
etpNotCreated = 0
for tbz2 in tbz2files:
counter += 1
tbz2name = tbz2.split("/")[len(tbz2.split("/"))-1]
print_info(" ("+str(counter)+"/"+str(totalCounter)+") Processing "+tbz2name)
tbz2path = etpConst['packagesstoredir']+"/"+tbz2
rc, newFileName, idpk = generator(tbz2path, dbconn, enzymeRequestBranch)
if (rc):
etpCreated += 1
# move the file with its new name
spawnCommand("mv "+tbz2path+" "+etpConst['packagessuploaddir']+"/"+enzymeRequestBranch+"/"+newFileName+" -f")
print_info(yellow(" * ")+red("Injecting database information into ")+bold(newFileName)+red(", please wait..."), back = True)
dbpath = etpConst['packagestmpdir']+"/"+"data.db"
# create db
pkgDbconn = databaseTools.etpDatabase(readOnly = False, noUpload = True, dbFile = dbpath, clientDatabase = True)
pkgDbconn.initializeDatabase()
data = dbconn.getPackageData(idpk)
rev = dbconn.retrieveRevision(idpk)
# inject
pkgDbconn.addPackage(data, revision = rev, wantedBranch = data['branch'])
pkgDbconn.closeDB()
# append the database to the new file
aggregateEntropyDb(tbz2file = etpConst['packagessuploaddir']+"/"+enzymeRequestBranch+"/"+newFileName, dbfile = dbpath)
digest = md5sum(etpConst['packagessuploaddir']+"/"+enzymeRequestBranch+"/"+newFileName)
dbconn.setDigest(idpk,digest)
hashFilePath = createHashFile(etpConst['packagessuploaddir']+"/"+enzymeRequestBranch+"/"+newFileName)
# remove garbage
spawnCommand("rm -rf "+dbpath)
print_info(yellow(" * ")+red("Database injection complete for ")+newFileName)
else:
etpNotCreated += 1
spawnCommand("rm -rf "+tbz2path)
dbconn.commitChanges()
dbconn.commitChanges()
# regen dependstable
dependsTableInitialize(dbconn, False)
dbconn.closeDB()
print_info(green(" * ")+red("Statistics: ")+blue("Entries created/updated: ")+bold(str(etpCreated))+yellow(" - ")+darkblue("Entries discarded: ")+bold(str(etpNotCreated)))
# This function extracts all the info from a .tbz2 file and returns them
def extractPkgData(package, etpBranch = etpConst['branch']):
reagentLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_VERBOSE,"extractPkgData: called -> package: "+str(package))
info_package = bold(os.path.basename(package))+": "
# Clean the variables
for i in etpData:
etpData[i] = u""
print_info(yellow(" * ")+red(info_package+"Getting package name/version..."),back = True)
tbz2File = package
package = package.split(".tbz2")[0]
if package.split("-")[len(package.split("-"))-1].startswith("t"):
package = string.join(package.split("-t")[:len(package.split("-t"))-1],"-t")
package = package.split("-")
pkgname = ""
pkglen = len(package)
if package[pkglen-1].startswith("r"):
pkgver = package[pkglen-2]+"-"+package[pkglen-1]
pkglen -= 2
else:
pkgver = package[len(package)-1]
pkglen -= 1
for i in range(pkglen):
if i == pkglen-1:
pkgname += package[i]
else:
pkgname += package[i]+"-"
pkgname = pkgname.split("/")[len(pkgname.split("/"))-1]
# Fill Package name and version
etpData['name'] = pkgname
etpData['version'] = pkgver
print_info(yellow(" * ")+red(info_package+"Getting package md5..."),back = True)
# .tbz2 md5
etpData['digest'] = md5sum(tbz2File)
print_info(yellow(" * ")+red(info_package+"Getting package mtime..."),back = True)
# .tbz2 md5
etpData['datecreation'] = str(getFileUnixMtime(tbz2File))
print_info(yellow(" * ")+red(info_package+"Getting package size..."),back = True)
# .tbz2 byte size
etpData['size'] = str(os.stat(tbz2File)[6])
print_info(yellow(" * ")+red(info_package+"Unpacking package data..."),back = True)
# unpack file
tbz2TmpDir = etpConst['packagestmpdir']+"/"+etpData['name']+"-"+etpData['version']+"/"
extractXpak(tbz2File,tbz2TmpDir)
print_info(yellow(" * ")+red(info_package+"Getting package CHOST..."),back = True)
# Fill chost
f = open(tbz2TmpDir+dbCHOST,"r")
etpData['chost'] = f.readline().strip()
f.close()
print_info(yellow(" * ")+red(info_package+"Setting package branch..."),back = True)
# always unstable when created
i = etpConst['branches'].index(etpBranch)
etpData['branch'] = etpConst['branches'][i]
print_info(yellow(" * ")+red(info_package+"Getting package description..."),back = True)
# Fill description
etpData['description'] = ""
try:
f = open(tbz2TmpDir+dbDESCRIPTION,"r")
etpData['description'] = f.readline().strip()
f.close()
except IOError:
pass
print_info(yellow(" * ")+red(info_package+"Getting package homepage..."),back = True)
# Fill homepage
etpData['homepage'] = ""
try:
f = open(tbz2TmpDir+dbHOMEPAGE,"r")
etpData['homepage'] = f.readline().strip()
f.close()
except IOError:
pass
print_info(yellow(" * ")+red(info_package+"Getting package slot information..."),back = True)
# fill slot, if it is
etpData['slot'] = ""
try:
f = open(tbz2TmpDir+dbSLOT,"r")
etpData['slot'] = f.readline().strip()
f.close()
except IOError:
pass
print_info(yellow(" * ")+red(info_package+"Getting package content..."),back = True)
# dbCONTENTS
etpData['content'] = []
try:
f = open(tbz2TmpDir+dbCONTENTS,"r")
content = f.readlines()
f.close()
outcontent = []
for line in content:
line = line.strip().split()
if (line[0] == "obj") or (line[0] == "sym"):
# remove first object (obj or sym)
datafile = line[1:]
# remove checksum and mtime - obj and sym have it
try:
if line[0] == "obj":
datafile = datafile[:len(datafile)-2]
else:
datafile = datafile[:len(datafile)-3]
datafile = string.join(datafile,' ')
except:
datafile = datafile[0] # FIXME: handle shit better
outcontent.append(datafile)
# filter bad utf-8 chars
_outcontent = []
for i in outcontent:
try:
i = i.encode(sys.getfilesystemencoding())
_outcontent.append(i)
except:
pass
outcontent = _outcontent
for i in outcontent:
etpData['content'].append(i.encode("utf-8"))
except IOError:
pass
# files size on disk
if (etpData['content']):
etpData['disksize'] = 0
for file in etpData['content']:
try:
size = os.stat(file)[6]
etpData['disksize'] += size
except:
pass
else:
etpData['disksize'] = 0
# [][][] Kernel dependent packages hook [][][]
kernelDependentModule = False
for file in etpData['content']:
if file.find("/lib/modules/") != -1:
kernelDependentModule = True
# get the version of the modules
kmodver = file.split("/lib/modules/")[1]
kmodver = kmodver.split("/")[0]
# substitute "-" with "_"
kmodver = re.subn("-","_", kmodver)
if len(kmodver) >= 2:
kmodver = kmodver[0]
lp = kmodver.split("-")[len(kmodver.split("-"))-1]
if lp.startswith("r"):
kname = kmodver.split("_")[len(kmodver.split("_"))-2]
kver = kmodver.split("_")[0]+"-"+kmodver.split("_")[len(kmodver.split("_"))-1]
else:
kname = kmodver.split("_")[len(kmodver.split("_"))-1]
kver = kmodver.split("_")[0]
break
# validate the results above
if (kernelDependentModule):
matchatom = "linux-"+kname+"-"+kver
if (matchatom == etpData['name']+"-"+etpData['version']):
# discard
kernelDependentModule = False
# add strict kernel dependency
# done below
print_info(yellow(" * ")+red(info_package+"Getting package download URL..."),back = True)
# Fill download relative URI
if (kernelDependentModule):
etpData['versiontag'] = "t"+kmodver
versiontag = "-"+etpData['versiontag']
else:
versiontag = ""
etpData['download'] = etpConst['binaryurirelativepath']+etpData['branch']+"/"+etpData['name']+"-"+etpData['version']+versiontag+".tbz2"
print_info(yellow(" * ")+red(info_package+"Getting package counter..."),back = True)
# Fill category
f = open(tbz2TmpDir+dbCOUNTER,"r")
etpData['counter'] = f.readline().strip()
f.close()
print_info(yellow(" * ")+red(info_package+"Getting package category..."),back = True)
# Fill category
f = open(tbz2TmpDir+dbCATEGORY,"r")
etpData['category'] = f.readline().strip()
f.close()
print_info(yellow(" * ")+red(info_package+"Getting package CFLAGS..."),back = True)
# Fill CFLAGS
etpData['cflags'] = ""
try:
f = open(tbz2TmpDir+dbCFLAGS,"r")
etpData['cflags'] = f.readline().strip()
f.close()
except IOError:
pass
print_info(yellow(" * ")+red(info_package+"Getting package CXXFLAGS..."),back = True)
# Fill CXXFLAGS
etpData['cxxflags'] = ""
try:
f = open(tbz2TmpDir+dbCXXFLAGS,"r")
etpData['cxxflags'] = f.readline().strip()
f.close()
except IOError:
pass
print_info(yellow(" * ")+red(info_package+"Getting package License information..."),back = True)
# Fill license
etpData['license'] = []
try:
f = open(tbz2TmpDir+dbLICENSE,"r")
# strip away || ( )
tmpLic = f.readline().strip().split()
f.close()
for x in tmpLic:
if x:
if (not x.startswith("|")) and (not x.startswith("(")) and (not x.startswith(")")):
etpData['license'].append(x)
etpData['license'] = string.join(etpData['license']," ")
except IOError:
etpData['license'] = ""
pass
print_info(yellow(" * ")+red(info_package+"Getting package USE flags..."),back = True)
# Fill USE
etpData['useflags'] = []
f = open(tbz2TmpDir+dbUSE,"r")
tmpUSE = f.readline().strip()
f.close()
try:
f = open(tbz2TmpDir+dbIUSE,"r")
tmpIUSE = f.readline().strip().split()
f.close()
except IOError:
tmpIUSE = []
PackageFlags = []
for x in tmpUSE.split():
if (x):
PackageFlags.append(x)
for i in tmpIUSE:
try:
PackageFlags.index(i)
etpData['useflags'].append(i)
except:
etpData['useflags'].append("-"+i)
print_info(yellow(" * ")+red(info_package+"Getting package provide content..."),back = True)
# Fill Provide
etpData['provide'] = []
try:
f = open(tbz2TmpDir+dbPROVIDE,"r")
provide = f.readline().strip()
f.close()
if (provide):
provide = provide.split()
for x in provide:
etpData['provide'].append(x)
except:
pass
print_info(yellow(" * ")+red(info_package+"Getting package sources information..."),back = True)
# Fill sources
etpData['sources'] = []
try:
f = open(tbz2TmpDir+dbSRC_URI,"r")
sources = f.readline().strip().split()
f.close()
tmpData = []
cnt = -1
skip = False
etpData['sources'] = []
for source in sources:
cnt += +1
if source.endswith("?"):
# it's an use flag
source = source[:len(source)-1]
direction = True
if source.startswith("!"):
direction = False
source = source[1:]
# now get the useflag
useflag = False
try:
etpData['useflags'].index(source)
useflag = True
except:
pass
if (useflag) and (direction): # useflag is enabled and it's asking for sources or useflag is not enabled and it's not not (= True) asking for sources
# ack parsing from ( to )
skip = False
elif (useflag) and (not direction):
# deny parsing from ( to )
skip = True
elif (not useflag) and (direction):
# deny parsing from ( to )
skip = True
else:
# ack parsing from ( to )
skip = False
elif source.startswith(")"):
# reset skip
skip = False
elif (not source.startswith("(")):
if (not skip):
etpData['sources'].append(source)
except IOError:
pass
print_info(yellow(" * ")+red(info_package+"Getting package mirrors list..."),back = True)
# manage etpData['sources'] to create etpData['mirrorlinks']
# =mirror://openoffice|link1|link2|link3
etpData['mirrorlinks'] = []
for i in etpData['sources']:
if i.startswith("mirror://"):
# parse what mirror I need
mirrorURI = i.split("/")[2]
mirrorlist = getThirdPartyMirrors(mirrorURI)
etpData['mirrorlinks'].append([mirrorURI,mirrorlist]) # mirrorURI = openoffice and mirrorlist = [link1, link2, link3]
print_info(yellow(" * ")+red(info_package+"Getting source package supported ARCHs..."),back = True)
# fill KEYWORDS
etpData['keywords'] = []
try:
f = open(tbz2TmpDir+dbKEYWORDS,"r")
cnt = f.readline().strip().split()
for i in cnt:
if i:
etpData['keywords'].append(i)
f.close()
except IOError:
pass
print_info(yellow(" * ")+red(info_package+"Getting package supported ARCHs..."),back = True)
# fill ARCHs
kwords = etpData['keywords']
_kwords = []
for i in kwords:
if i.startswith("~"):
i = i[1:]
_kwords.append(i)
etpData['binkeywords'] = []
for i in etpConst['supportedarchs']:
try:
x = _kwords.index(i)
etpData['binkeywords'].append(i)
except:
pass
print_info(yellow(" * ")+red(info_package+"Getting package dependencies..."),back = True)
# Fill dependencies
# to fill dependencies we use *DEPEND files
f = open(tbz2TmpDir+dbRDEPEND,"r")
roughDependencies = f.readline().strip()
f.close()
if (not roughDependencies):
f = open(tbz2TmpDir+dbDEPEND,"r")
roughDependencies = f.readline().strip()
f.close()
f = open(tbz2TmpDir+dbPDEPEND,"r")
roughDependencies += " "+f.readline().strip()
f.close()
roughDependencies = roughDependencies.split()
# variables filled
# etpData['dependencies'], etpData['conflicts']
deps,conflicts = synthetizeRoughDependencies(roughDependencies,string.join(PackageFlags," "))
etpData['dependencies'] = []
for i in deps.split():
etpData['dependencies'].append(i)
etpData['conflicts'] = []
for i in conflicts.split():
# check if i == PROVIDE
if i not in etpData['provide']: # we handle these conflicts using emerge, so we can just filter them out
etpData['conflicts'].append(i)
if (kernelDependentModule):
# add kname to the dependency
etpData['dependencies'].append("sys-kernel/linux-"+kname+"-"+kver)
print_info(yellow(" * ")+red(info_package+"Getting System package List..."),back = True)
# write only if it's a systempackage
systemPackages = getPackagesInSystem()
for x in systemPackages:
x = dep_getkey(x)
y = etpData['category']+"/"+etpData['name']
if x == y:
# found
etpData['systempackage'] = "xxx"
break
print_info(yellow(" * ")+red(info_package+"Getting CONFIG_PROTECT/CONFIG_PROTECT_MASK List..."),back = True)
# write only if it's a systempackage
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
etpData['etpapi'] = etpConst['etpapi']
# removing temporary directory
os.system("rm -rf "+tbz2TmpDir)
print_info(yellow(" * ")+red(info_package+"Done"),back = True)
return etpData
def dependsTableInitialize(dbconn = None, runActivator = True):
closedb = False
if dbconn == None:
dbconn = databaseTools.etpDatabase(readOnly = False, noUpload = True)
closedb = True
dbconn.regenerateDependsTable()
# now taint
dbconn.taintDatabase()
if (closedb):
dbconn.closeDB()
# running activator
if (runActivator):
import activatorTools
activatorTools.database(['sync'])
def dependenciesTest(options):
reagentRequestQuiet = False
for opt in options:
if opt.startswith("--quiet"):
reagentRequestQuiet = True
if (not reagentRequestQuiet):
print_info(red(" @@ ")+blue("ATTENTION: you need to have equo.conf properly configured only for your running repository !!"))
print_info(red(" @@ ")+blue("Running dependency test..."))
dbconn = databaseTools.etpDatabase(readOnly = True)
# hey Equo, how are you?
sys.path.append('../client')
import equoTools
equoTools.syncRepositories(quiet = reagentRequestQuiet)
# get all the installed packages
installedPackages = dbconn.listAllIdpackages()
depsNotFound = {}
depsNotSatisfied = {}
# now look
length = str((len(installedPackages)))
count = 0
for xidpackage in installedPackages:
count += 1
atom = dbconn.retrieveAtom(xidpackage)
if (not reagentRequestQuiet):
print_info(darkred(" @@ ")+bold("(")+blue(str(count))+"/"+red(length)+bold(")")+darkgreen(" Checking ")+bold(atom), back = True)
deptree, status = equoTools.generateDependencyTree([xidpackage,0])
if (status == -2): # dependencies not found
depsNotFound[xidpackage] = []
if (deptree):
for x in deptree:
depsNotFound[xidpackage].append(x)
elif (status == 0):
# FIXME: add conflicts handling (aka, show up something!)
conflicts = deptree.get(0,None)
if (conflicts):
print conflicts
deptree[0] = []
depsNotSatisfied[xidpackage] = []
for x in range(len(deptree))[::-1]:
for z in deptree[x]:
depsNotSatisfied[xidpackage].append(z)
if (not depsNotSatisfied[xidpackage]):
del depsNotSatisfied[xidpackage]
packagesNeeded = []
if (depsNotSatisfied):
if (not reagentRequestQuiet):
print_info(red(" @@ ")+blue("These are the packages that lack dependencies: "))
for dict in depsNotSatisfied:
pkgatom = dbconn.retrieveAtom(dict)
if (not reagentRequestQuiet):
print_info(darkred(" ### ")+blue(pkgatom))
for dep in depsNotSatisfied[dict]:
depatom = dbconn.retrieveAtom(dep)
if (not reagentRequestQuiet):
print_info(bold(" :: ")+red(depatom))
packagesNeeded.append([depatom,dep])
packagesNotFound = []
if (depsNotFound):
if (not reagentRequestQuiet):
print_info(red(" @@ ")+blue("These are the packages not found, that respective packages in repository need:"))
for dict in depsNotFound:
pkgatom = dbconn.retrieveAtom(dict)
if (not reagentRequestQuiet):
print_info(darkred(" ### ")+blue(pkgatom))
for pkg in depsNotFound[dict]:
if (not reagentRequestQuiet):
print_info(bold(" :: ")+red(pkg))
packagesNotFound.append(pkg)
packagesNotFound = filterDuplicatedEntries(packagesNotFound)
if (reagentRequestQuiet):
for x in packagesNotFound:
print x
dbconn.closeDB()
return 0,packagesNeeded,packagesNotFound
def smartapps(options):
reagentLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_VERBOSE,"smartapps: called -> options: "+str(options))
if (len(options) == 0):
print_error(yellow(" * ")+red("No valid tool specified."))
sys.exit(501)
if (options[0] == "create"):
myopts = options[1:]
if (len(myopts) == 0):
print_error(yellow(" * ")+red("No packages specified."))
sys.exit(502)
# open db
dbconn = databaseTools.etpDatabase(readOnly = True)
# seek valid apps (in db)
validPackages = []
for opt in myopts:
pkgsfound = dbconn.searchPackages(opt)
for pkg in pkgsfound:
validPackages.append(pkg)
dbconn.closeDB()
if (len(validPackages) == 0):
print_error(yellow(" * ")+red("No valid packages specified."))
sys.exit(503)
print_info(red(" @@ ")+blue("ATTENTION: you need to have equo.conf properly configured only for your running repository !!"))
sys.path.append('../client')
import equoTools
equoTools.syncRepositories()
# print the list
print_info(green(" * ")+red("This is the list of the packages that would be worked out:"))
for pkg in validPackages:
print_info(green("\t[SMART] - ")+bold(pkg[0]))
rc = askquestion(">> Would you like to create the packages above ?")
if rc == "No":
sys.exit(0)
for pkg in validPackages:
print_info(green(" * ")+red("Creating smartapp package from ")+bold(pkg[0]))
smartgenerator(pkg)
print_info(green(" * ")+red("Smartapps creation done, remember to test them before publishing."))
# tool that generates .tar.bz2 packages with all the binary dependencies included
# @returns the package file path
# NOTE: this section is highly portage dependent
def smartgenerator(atomInfo):
reagentLog.log(ETP_LOGPRI_INFO,ETP_LOGLEVEL_VERBOSE,"smartgenerator: called -> package: "+str(atomInfo))
dbconn = databaseTools.etpDatabase(readOnly = True)
sys.path.append('../client')
import equoTools
idpackage = atomInfo[1]
atom = atomInfo[0]
# check if the application package is available, otherwise, download
pkgfilepath = dbconn.retrieveDownloadURL(idpackage)
pkgcontent = dbconn.retrieveContent(idpackage)
pkgbranch = dbconn.retrieveBranch(idpackage)
pkgfilename = os.path.basename(pkgfilepath)
pkgname = pkgfilename.split(".tbz2")[0]
pkgdependencies, result = equoTools.getRequiredPackages([[idpackage,etpConst['officialrepositoryname']]], emptydeps = True)
# flatten them
pkgs = []
if (result == 0):
for x in range(len(pkgdependencies))[::-1]:
#print x
for z in pkgdependencies[x]:
#print treepackages[x][z]
for a in pkgdependencies[x][z]:
pkgs.append(a)
elif (result == -2):
print_error(green(" * ")+red("Missing dependencies: ")+str(pkgdependencies))
sys.exit(505)
elif (result == -1):
print_error(green(" * ")+red("Database file not found or no database connection. --> ")+str(pkgdependencies))
sys.exit(506)
print_info(green(" * ")+red("This is the list of the dependencies that would be included:"))
for i in pkgs:
atom = dbconn.retrieveAtom(i[0])
print_info(green(" [] ")+red(atom))
# create the working directory
pkgtmpdir = etpConst['packagestmpdir']+"/"+pkgname
#print "DEBUG: "+pkgtmpdir
if os.path.isdir(pkgtmpdir):
spawnCommand("rm -rf "+pkgtmpdir)
mainBinaryPath = etpConst['packagesbindir']+"/"+pkgbranch+"/"+pkgfilename
print_info(green(" * ")+red("Unpacking main package ")+bold(str(pkgfilename)))
uncompressTarBz2(mainBinaryPath,pkgtmpdir) # first unpack
binaryExecs = []
for file in pkgcontent:
# remove /
filepath = pkgtmpdir+file
import commands
if os.access(filepath,os.X_OK):
# test if it's an exec
out = commands.getoutput("file "+filepath).split("\n")[0]
if out.find("LSB executable") != -1:
binaryExecs.append(file)
# check if file is executable
# now uncompress all the rest
for dep in pkgs:
download = os.path.basename(dbconn.retrieveDownloadURL(dep[0]))
depbranch = dbconn.retrieveBranch(dep[0])
print_info(green(" * ")+red("Unpacking dependency package ")+bold(str(download)))
deppath = etpConst['packagesbindir']+"/"+depbranch+"/"+download
uncompressTarBz2(deppath,pkgtmpdir) # first unpack
# remove unwanted files (header files)
os.system('for file in `find '+contentdir+' -name "*.h"`; do rm $file; done')
# now create the bash script for each binaryExecs
os.makedirs(contentdir+"/wrp")
bashScript = []
bashScript.append(
'#!/bin/sh\n'
'cd $1\n'
'MYPYP=$(find $PWD/lib/python2.4/site-packages/ -type d -printf %p: 2> /dev/null)\n'
'MYPYP2=$(find $PWD/lib/python2.5/site-packages/ -type d -printf %p: 2> /dev/null)\n'
'export PYTHONPATH=$MYPYP:MYPYP2:$PYTHONPATH\n'
'export PATH=$PWD:$PWD/sbin:$PWD/bin:$PWD/usr/bin:$PWD/usr/sbin:$PWD/usr/X11R6/bin:$PWD/libexec:$PWD/usr/local/bin:$PWD/usr/local/sbin:$PATH\n'
'export LD_LIBRARY_PATH='
'$PWD/lib:'
'$PWD/lib64:'
'$PWD/usr/lib:'
'$PWD/usr/lib64:'
'$PWD/usr/lib/nss:'
'$PWD/usr/lib/nspr:'
'$PWD/usr/lib64/nss:'
'$PWD/usr/lib64/nspr:'
'$PWD/usr/qt/3/lib:'
'$PWD/usr/qt/3/lib64:'
'$PWD/usr/kde/3.5/lib:'
'$PWD/usr/kde/3.5/lib64:'
'$LD_LIBRARY_PATH\n'
'export KDEDIRS=$PWD/usr/kde/3.5:$PWD/usr:$KDEDIRS\n'
'export PERL5LIB=$PWD/usr/lib/perl5:$PWD/share/perl5:$PWD/usr/lib/perl5/5.8.1'
':$PWD/usr/lib/perl5/5.8.2:'
':$PWD/usr/lib/perl5/5.8.3:'
':$PWD/usr/lib/perl5/5.8.4:'
':$PWD/usr/lib/perl5/5.8.5:'
':$PWD/usr/lib/perl5/5.8.6:'
':$PWD/usr/lib/perl5/5.8.7:'
':$PWD/usr/lib/perl5/5.8.8:'
':$PWD/usr/lib/perl5/5.8.9:'
':$PWD/usr/lib/perl5/5.8.10\n'
'export MANPATH=$PWD/share/man:$MANPATH\n'
'export GUILE_LOAD_PATH=$PWD/share/:$GUILE_LOAD_PATH\n'
'export SCHEME_LIBRARY_PATH=$PWD/share/slib:$SCHEME_LIBRARY_PATH\n'
'# Setup pango\n'
'MYPANGODIR=$(find $PWD/usr/lib/pango -name modules)\n'
'if [ -n "$MYPANGODIR" ]; then\n'
' export PANGO_RC_FILE=$PWD/etc/pango/pangorc\n'
' echo "[Pango]" > $PANGO_RC_FILE\n'
' echo "ModulesPath=${MYPANGODIR}" >> $PANGO_RC_FILE\n'
' echo "ModuleFiles=${PWD}/etc/pango/pango.modules" >> $PANGO_RC_FILE\n'
' pango-querymodules > ${PWD}/etc/pango/pango.modules\n'
'fi\n'
'$2\n'
)
f = open(contentdir+"/wrp/wrapper","w")
f.writelines(bashScript)
f.flush()
f.close()
# chmod
os.chmod(contentdir+"/wrp/wrapper",0755)
# now list files in /sh and create .desktop files
for file in binaryExecs:
file = file.split("/")[len(file.split("/"))-1]
runFile = []
runFile.append(
'#include <cstdlib>\n'
'#include <cstdio>\n'
'#include <stdio.h>\n'
'int main() {\n'
' int rc = system(\n'
' "pid=$(pidof '+file+'.exe);"\n'
' "listpid=$(ps x | grep $pid);"\n'
' "filename=$(echo $listpid | cut -d\' \' -f 5);"'
' "currdir=$(dirname $filename);"\n'
' "/bin/sh $currdir/wrp/wrapper $currdir '+file+'" );\n'
' return rc;\n'
'}\n'
)
f = open(contentdir+"/"+file+".cc","w")
f.writelines(runFile)
f.flush()
f.close()
# now compile
spawnCommand("cd "+contentdir+"/ ; g++ -Wall "+file+".cc -o "+file+".exe")
os.remove(contentdir+"/"+file+".cc")
# now compress in .tar.bz2 and place in etpConst['smartappsdir']
#print etpConst['smartappsdir']+"/"+pkgname+"-"+etpConst['currentarch']+".tar.bz2"
#print pkgtmpdir+"/"
compressTarBz2(etpConst['smartappsdir']+"/"+pkgname+"-"+etpConst['currentarch']+".tbz2",contentdir+"/")
dbconn.closeDB()