import sys
import os.path
from PackageUtils import PackageUtils
from Logger import Logger
from ToolChainUtils import ToolChainUtils
from CommandUtils import CommandUtils
from constants import constants
from SpecData import SPECS
from StringUtils import StringUtils
from Sandbox import Chroot, Container
class PackageBuilder(object):
def __init__(self, mapPackageToCycles, sandboxType):
# will be initialized in buildPackageFunction()
self.logName = None
self.logPath = None
self.logger = None
self.package = None
self.version = None
self.doneList = None
self.sandboxType = sandboxType
self.sandbox = None
self.mapPackageToCycles = mapPackageToCycles
self.listNodepsPackages = ["glibc", "gmp", "zlib", "file", "binutils", "mpfr",
"mpc", "gcc", "ncurses", "util-linux", "groff", "perl",
"texinfo", "rpm", "openssl", "go"]
def build(self, pkg, doneList):
packageName, packageVersion = StringUtils.splitPackageNameAndVersion(pkg)
#do not build if RPM is already built
#test only if the package is in the testForceRPMS with rpmCheck
#build only if the package is not in the testForceRPMS with rpmCheck
if not constants.rpmCheck or packageName in constants.testForceRPMS:
if self._checkIfPackageIsAlreadyBuilt(packageName, packageVersion, doneList):
return
self._buildPackagePrepareFunction(packageName, packageVersion, doneList)
try:
self._buildPackage()
except Exception as e:
# TODO: self.logger might be None
self.logger.exception(e)
raise e
def _buildPackage(self):
try:
self.sandbox.create(self.package + "-" + self.version)
tUtils = ToolChainUtils(self.logName, self.logPath)
if self.sandbox.hasToolchain():
tUtils.installExtraToolchainRPMS(self.sandbox, self.package, self.version)
else:
tUtils.installToolchainRPMS(self.sandbox, self.package, self.version, availablePackages=self.doneList)
listDependentPackages, listTestPackages, listInstalledPackages, listInstalledRPMs = (
self._findDependentPackagesAndInstalledRPM(self.sandbox))
pkgUtils = PackageUtils(self.logName, self.logPath)
if listDependentPackages:
self.logger.debug("Installing the build time dependent packages......")
for pkg in listDependentPackages:
packageName, packageVersion = StringUtils.splitPackageNameAndVersion(pkg)
self._installPackage(pkgUtils, packageName, packageVersion, self.sandbox, self.logPath,listInstalledPackages, listInstalledRPMs)
for pkg in listTestPackages:
flag = False
packageName, packageVersion = StringUtils.splitPackageNameAndVersion(pkg)
for depPkg in listDependentPackages:
depPackageName, depPackageVersion = StringUtils.splitPackageNameAndVersion(depPkg)
if depPackageName == packageName:
flag = True
break;
if flag == False:
self._installPackage(pkgUtils, packageName,packageVersion, self.sandbox, self.logPath,listInstalledPackages, listInstalledRPMs)
pkgUtils.installRPMSInOneShot(self.sandbox)
self.logger.debug("Finished installing the build time dependent packages....")
pkgUtils.adjustGCCSpecs(self.sandbox, self.package, self.version)
pkgUtils.buildRPMSForGivenPackage(self.sandbox, self.package, self.version,
self.logPath)
self.logger.debug("Successfully built the package: " + self.package)
except Exception as e:
self.logger.error("Failed while building package: " + self.package)
self.logger.debug("Sandbox: " + self.sandbox.getID() +
" not deleted for debugging.")
logFileName = os.path.join(self.logPath, self.package + ".log")
fileLog = os.popen('tail -n 100 ' + logFileName).read()
self.logger.info(fileLog)
raise e
if self.sandbox:
self.sandbox.destroy()
def _buildPackagePrepareFunction(self, package, version, doneList):
self.package = package
self.version = version
self.logName = "build-" + package + "-" + version
self.logPath = constants.logPath + "/" + package + "-" + version
if not os.path.isdir(self.logPath):
cmdUtils = CommandUtils()
cmdUtils.runCommandInShell("mkdir -p " + self.logPath)
self.logger = Logger.getLogger(self.logName, self.logPath, constants.logLevel)
self.doneList = doneList
if self.sandboxType == "chroot":
sandbox = Chroot(self.logger)
elif self.sandboxType == "container":
sandbox = Container(self.logger)
else:
raise Exception("Unknown sandbox type: " + sandboxType)
self.sandbox = sandbox
def _findPackageNameAndVersionFromRPMFile(self, rpmfile):
rpmfile = os.path.basename(rpmfile)
releaseindex = rpmfile.rfind("-")
if releaseindex == -1:
self.logger.error("Invalid rpm file:" + rpmfile)
return None
pkg = rpmfile[0:releaseindex]
return pkg
def _findInstalledPackages(self, sandbox):
pkgUtils = PackageUtils(self.logName, self.logPath)
listInstalledRPMs = pkgUtils.findInstalledRPMPackages(sandbox)
listInstalledPackages = []
for installedRPM in listInstalledRPMs:
pkg = self._findPackageNameAndVersionFromRPMFile(installedRPM)
if pkg is not None:
listInstalledPackages.append(pkg)
return listInstalledPackages, listInstalledRPMs
def _checkIfPackageIsAlreadyBuilt(self, package, version, doneList):
basePkg = SPECS.getData().getSpecName(package) + "-" + version
return basePkg in doneList
def _findRunTimeRequiredRPMPackages(self, rpmPackage, version):
return SPECS.getData().getRequiresForPackage(rpmPackage, version)
def _findBuildTimeRequiredPackages(self):
return SPECS.getData().getBuildRequiresForPackage(self.package, self.version)
def _findBuildTimeCheckRequiredPackages(self):
return SPECS.getData().getCheckBuildRequiresForPackage(self.package, self.version)
def _installPackage(self, pkgUtils, package, packageVersion, sandbox, destLogPath,
listInstalledPackages, listInstalledRPMs):
rpmfile = pkgUtils.findRPMFile(package,packageVersion);
if rpmfile is None:
self.logger.error("No rpm file found for package: " + package + "-" + packageVersion)
raise Exception("Missing rpm file")
specificRPM = os.path.basename(rpmfile.replace(".rpm", ""))
pkg = package+"-"+packageVersion
if pkg in listInstalledPackages:
return
# mark it as installed - to avoid cyclic recursion
listInstalledPackages.append(pkg)
listInstalledRPMs.append(specificRPM)
self._installDependentRunTimePackages(pkgUtils, package, packageVersion, sandbox, destLogPath,
listInstalledPackages, listInstalledRPMs)
noDeps = False
if (package in self.mapPackageToCycles or
package in self.listNodepsPackages or
package in constants.noDepsPackageList):
noDeps = True
pkgUtils.prepRPMforInstall(package,packageVersion, noDeps, destLogPath)
def _installDependentRunTimePackages(self, pkgUtils, package, packageVersion, sandbox, destLogPath,
listInstalledPackages, listInstalledRPMs):
listRunTimeDependentPackages = self._findRunTimeRequiredRPMPackages(package, packageVersion)
if listRunTimeDependentPackages:
for pkg in listRunTimeDependentPackages:
if pkg in self.mapPackageToCycles:
continue
packageName, packageVersion = StringUtils.splitPackageNameAndVersion(pkg)
rpmfile = pkgUtils.findRPMFile(packageName, packageVersion)
if rpmfile is None:
self.logger.error("No rpm file found for package: " + packageName + "-" + packageVersion)
raise Exception("Missing rpm file")
latestPkgRPM = os.path.basename(rpmfile).replace(".rpm", "")
if pkg in listInstalledPackages and latestPkgRPM in listInstalledRPMs:
continue
self._installPackage(pkgUtils, packageName,packageVersion, sandbox, destLogPath,listInstalledPackages, listInstalledRPMs)
def _findDependentPackagesAndInstalledRPM(self, sandbox):
listInstalledPackages, listInstalledRPMs = self._findInstalledPackages(sandbox)
self.logger.debug(listInstalledPackages)
listDependentPackages = self._findBuildTimeRequiredPackages()
listTestPackages=[]
if constants.rpmCheck and self.package in constants.testForceRPMS:
# One time optimization
if constants.listMakeCheckRPMPkgWithVersionstoInstall is None:
constants.listMakeCheckRPMPkgWithVersionstoInstall=[]
for package in constants.listMakeCheckRPMPkgtoInstall:
version = SPECS.getData().getHighestVersion(package)
constants.listMakeCheckRPMPkgWithVersionstoInstall.append(package+"-"+version)
listDependentPackages.extend(self._findBuildTimeCheckRequiredPackages())
testPackages = (set(constants.listMakeCheckRPMPkgWithVersionstoInstall) -
set(listInstalledPackages) -
set([self.package+"-"+self.version]))
listTestPackages=list(set(testPackages))
listDependentPackages = list(set(listDependentPackages))
return listDependentPackages, listTestPackages, listInstalledPackages, listInstalledRPMs