support/package-builder/ToolChainUtils.py
87815216
 import os.path
 import platform
 import traceback
2820c61a
 from CommandUtils import CommandUtils
 from ChrootUtils import ChrootUtils
 from Logger import Logger
 from PackageUtils import PackageUtils
 from constants import constants
 
 class ToolChainUtils(object):
5fc28b16
 
87815216
     def __init__(self, logName=None, logPath=None):
2820c61a
         if logName is None:
             logName = "Toolchain Utils"
         if logPath is None:
             logPath = constants.logPath
87815216
         self.logName = logName
         self.logPath = logPath
         self.logger = Logger.getLogger(logName, logPath)
2820c61a
         self.adjustToolChainScript = "adjust-tool-chain.sh"
         self.localegenScript = "./locale-gen.sh"
         self.localegenConfig = "./locale-gen.conf"
87815216
         self.prepareBuildRootCmd = "./prepare-build-root.sh"
58120db4
         self.rpmbuildCommand = "rpmbuild"
87815216
         if os.geteuid() == 0:
             self.rpmCommand = "rpm"
45e37dfb
         else:
87815216
             self.rpmCommand = "fakeroot-ng rpm"
45e37dfb
 
87815216
     def prepareBuildRoot(self, chrootID):
387ea52d
         self.logger.info("Preparing build environment")
         cmdUtils = CommandUtils()
87815216
         cmdUtils.runCommandInShell("mkdir -p " + chrootID + "/dev")
         cmdUtils.runCommandInShell("mkdir -p " + chrootID + "/etc")
         cmdUtils.runCommandInShell("mkdir -p " + chrootID + "/proc")
         cmdUtils.runCommandInShell("mkdir -p " + chrootID + "/run")
         cmdUtils.runCommandInShell("mkdir -p " + chrootID + "/sys")
         cmdUtils.runCommandInShell("mkdir -p " + chrootID + "/tmp")
         cmdUtils.runCommandInShell("mkdir -p " + chrootID + constants.topDirPath)
         cmdUtils.runCommandInShell("mkdir -p " + chrootID + constants.topDirPath +
                                    "/RPMS/" + platform.machine())
         cmdUtils.runCommandInShell("mkdir -p " + chrootID + constants.topDirPath + "/RPMS/noarch")
         cmdUtils.runCommandInShell("mkdir -p " + chrootID + constants.topDirPath + "/SOURCES")
         cmdUtils.runCommandInShell("mkdir -p " + chrootID + constants.topDirPath + "/SPECS")
         cmdUtils.runCommandInShell("mkdir -p " + chrootID + constants.topDirPath + "/LOGS")
         cmdUtils.runCommandInShell("mkdir -p " + chrootID + constants.topDirPath + "/BUILD")
         cmdUtils.runCommandInShell("mkdir -p " + chrootID + constants.topDirPath + "/BUILDROOT")
5fc28b16
 
87815216
         prepareChrootCmd = self.prepareBuildRootCmd + " " + chrootID
         logFile = self.logPath + "/prepareBuildRoot.log"
         returnVal = cmdUtils.runCommandInShell(prepareChrootCmd, logFile)
387ea52d
         if not returnVal:
             self.logger.error("Prepare build root script failed.Unable to prepare chroot.")
             raise Exception("Prepare build root script failed")
2fcd8ac0
 
87815216
         self.logger.info("Successfully prepared chroot:" + chrootID)
2fcd8ac0
 
87815216
     def findRPMFileInGivenLocation(self, package, rpmdirPath):
a4a06c39
         cmdUtils = CommandUtils()
87815216
         listFoundRPMFiles = cmdUtils.findFile(package + "-*.rpm", rpmdirPath)
         listFilterRPMFiles = []
a4a06c39
         for f in listFoundRPMFiles:
87815216
             rpmFileName = os.path.basename(f)
             checkRPMName = rpmFileName.replace(package, "")
7acb019e
             rpmNameSplit = checkRPMName.split("-")
             if len(rpmNameSplit) == 3:
a4a06c39
                 listFilterRPMFiles.append(f)
87815216
         if len(listFilterRPMFiles) == 1:
a4a06c39
             return listFilterRPMFiles[0]
87815216
         if len(listFilterRPMFiles) == 0:
a4a06c39
             return None
87815216
         if len(listFilterRPMFiles) > 1:
             self.logger.error("Found multiple rpm files for given package in rpm directory." +
                               "Unable to determine the rpm file for package:" + package)
a4a06c39
             return None
5fc28b16
 
085306ae
     def buildCoreToolChainPackages(self):
7f9d2e12
         self.logger.info("Building core toolchain packages.....")
87815216
         chrootID = None
7418d2bf
         pkgCount = 0
518d6a6f
         try:
87815216
             pkgUtils = PackageUtils(self.logName, self.logPath)
fb300e7c
             for package in constants.listCoreToolChainPackages:
87815216
                 rpmPkg = pkgUtils.findRPMFileForGivenPackage(package)
0fae9cdd
                 if rpmPkg is not None:
                     continue
7f9d2e12
                 self.logger.info("Building core toolchain package: " + package)
87815216
                 chrUtils = ChrootUtils(self.logName, self.logPath)
                 chrootName = "build-"+package
                 destLogPath = constants.logPath + "/build-" + package
0fae9cdd
                 if not os.path.isdir(destLogPath):
                     cmdUtils = CommandUtils()
87815216
                     cmdUtils.runCommandInShell("mkdir -p " + destLogPath)
                 returnVal, chrootID = chrUtils.createChroot(chrootName)
a4a06c39
                 if not returnVal:
                     self.logger.error("Creating chroot failed")
                     raise Exception("creating chroot failed")
7f9d2e12
                 self.installToolChainRPMS(chrootID, package, destLogPath)
75a2daa5
                 pkgUtils.adjustGCCSpecs(package, chrootID, destLogPath)
085306ae
                 pkgUtils.buildRPMSForGivenPackage(package, chrootID, destLogPath)
7418d2bf
                 pkgCount += 1
a4a06c39
                 chrUtils.destroyChroot(chrootID)
87815216
                 chrootID = None
518d6a6f
             self.logger.info("Successfully built toolchain")
d355ea7e
             if chrootID is not None:
                 chrUtils.destroyChroot(chrootID)
518d6a6f
         except Exception as e:
             self.logger.error("Unable to build tool chain.")
d355ea7e
             # print stacktrace
             traceback.print_exc()
518d6a6f
             raise e
7418d2bf
         return pkgCount
87815216
 
     def installToolChainRPMS(self, chrootID, packageName, logPath=None):
7f9d2e12
         if logPath is None:
87815216
             logPath = self.logPath
b85e6bd0
         cmdUtils = CommandUtils()
1ffbd987
         self.prepareBuildRoot(chrootID)
         self.logger.info("Installing Tool Chain RPMS.......")
1eb9191f
         rpmFiles = ""
         packages = ""
fb300e7c
         for package in constants.listToolChainRPMsToInstall:
87815216
             pkgUtils = PackageUtils(self.logName, self.logPath)
5fc28b16
             rpmFile = None
6d17349b
             if constants.rpmCheck:
87815216
                 rpmFile = pkgUtils.findRPMFileForGivenPackage(package)
6d17349b
             else:
                 if (packageName not in constants.listToolChainRPMsToInstall or
87815216
                         constants.listToolChainRPMsToInstall.index(packageName) >
                         constants.listToolChainRPMsToInstall.index(package)):
                     rpmFile = pkgUtils.findRPMFileForGivenPackage(package)
1ffbd987
             if rpmFile is None:
9874e684
                 # sqlite-autoconf package was renamed, but it still published as sqlite-autoconf
9b9c0eac
                 if (package == "sqlite") and (platform.machine() == "x86_64"):
9874e684
                     package = "sqlite-autoconf"
87815216
                 rpmFile = self.findRPMFileInGivenLocation(package, constants.prevPublishRPMRepo)
1ffbd987
                 if rpmFile is None:
fb300e7c
                     if package in constants.listOfRPMsProvidedAfterBuild:
87815216
                         self.logger.info("No old version of " + package +
                                          " exists, skip until the new version is built")
d77dd20b
                         continue
87815216
                     self.logger.error("Unable to find rpm " + package +
                                       " in current and previous versions")
36c2f510
                     raise Exception("Input Error")
1ffbd987
             rpmFiles += " " + rpmFile
             packages += " " + package
1eb9191f
 
87815216
         self.logger.debug("Installing toolchain rpms:" + packages)
         cmd = (self.rpmCommand + " -i -v --nodeps --noorder --force --root " +
                chrootID +" --define \'_dbpath /var/lib/rpm\' "+ rpmFiles)
         retVal = cmdUtils.runCommandInShell(cmd, logPath + "/install_toolchain_rpms.log")
7f9d2e12
         if not retVal:
             self.logger.debug("Command Executed:" + cmd)
1ffbd987
             self.logger.error("Installing tool chain  failed")
36c2f510
             raise Exception("RPM installation failed")
87815216
         self.logger.info("Successfully installed default Tool Chain RPMS in Chroot:" + chrootID)
         print("Building Package: ".format(packageName))
         print(constants.perPackageToolChain)
27a75769
         if packageName in constants.perPackageToolChain:
87815216
             print(constants.perPackageToolChain[packageName])
             self.installCustomToolChainRPMS(chrootID, constants.perPackageToolChain[packageName],
                                             packageName)
 
27a75769
     def installCustomToolChainRPMS(self, chrootID, listOfToolChainPkgs, packageName):
87815216
         self.logger.info("Installing package specific tool chain RPMs for " + packageName +
                          ".......")
062d56d1
         rpmFiles = ""
         packages = ""
7f9d2e12
         cmdUtils = CommandUtils()
27a75769
         for package in listOfToolChainPkgs:
87815216
             pkgUtils = PackageUtils(self.logName, self.logPath)
             print("DEBUG:" + package)
8c91b2bd
             if "openjre8" in packageName or "openjdk8" in packageName:
a2cf8f06
                 # x86_64 has openjdk/jre as a published rpms but aarch64 has openjdk8/jre8
                 # Remove this condition after publishxrpms for x86_^4 got updated
87815216
                 if ((package == "openjdk" or package == "openjre") and
                         platform.machine() == "aarch64"):
a2cf8f06
                     package = package + "8"
87815216
                 rpmFile = self.findRPMFileInGivenLocation(package, constants.prevPublishXRPMRepo)
27a75769
             else:
87815216
                 rpmFile = self.findRPMFileInGivenLocation(package, constants.prevPublishRPMRepo)
062d56d1
             if rpmFile is None:
87815216
                 self.logger.error("Unable to find rpm "+ package +
                                   " in current and previous versions")
062d56d1
                 raise Exception("Input Error")
             rpmFiles += " " + rpmFile
             packages += " " + package
 
87815216
         self.logger.debug("Installing custom rpms:" + packages)
         cmd = (self.rpmCommand + " -i -v --nodeps --noorder --force --root " +
                chrootID + " --define \'_dbpath /var/lib/rpm\' " + rpmFiles)
         retVal = cmdUtils.runCommandInShell(cmd, self.logPath +
                                             "/install_custom_toolchain_rpms.log")
7f9d2e12
         if not retVal:
             self.logger.debug("Command Executed:" + cmd)
062d56d1
             self.logger.error("Installing tool chain  failed")
             raise Exception("RPM installation failed")
         self.logger.info("Successfully installed all Tool Chain X RPMS")
7418d2bf
 
     def installToolChainRPMSinContainer(self, containerID):
         self.logger.info("Installing tool-chain RPMS in container: " + containerID.short_id)
         rpmFiles = ""
         packages = ""
         pkgUtils = PackageUtils(self.logName, self.logPath)
         for package in constants.listToolChainRPMPkgsToInstall:
             rpmFile = pkgUtils.findRPMFileForGivenPackage(package)
             if rpmFile is None:
                 # sqlite-autoconf package was renamed, but it still published as sqlite-autoconf
9b9c0eac
 #                if (package == "sqlite") and (platform.machine() == "x86_64"):
0f1fdc4b
 #                    package = "sqlite-autoconf"
7418d2bf
                 rpmFile = self.findRPMFileInGivenLocation(package, constants.prevPublishRPMRepo)
                 if rpmFile is None:
                     if package in constants.listOfRPMsProvidedAfterBuild:
87815216
                         self.logger.info("No old version of " + package +
                                          " exists, skip until the new version is built")
7418d2bf
                         continue
87815216
                     self.logger.error("Unable to find rpm " + package +
                                       " in current and previous versions")
7418d2bf
                     raise Exception("Input Error")
             if rpmFile.find("stage/PUBLISHRPMS"):
                 rpmFile = rpmFile.replace(constants.prevPublishRPMRepo, "/publishrpms")
             if rpmFile.find("stage/PUBLISHXRPMS"):
                 rpmFile = rpmFile.replace(constants.prevPublishXRPMRepo, "/publishxrpms")
             if rpmFile.find("stage/RPMS"):
                 rpmFile = rpmFile.replace(constants.rpmPath, constants.topDirPath + "/RPMS")
             rpmFiles += " " + rpmFile
             packages += " " + package
 
         self.logger.debug("Installing tool-chain rpms: " + packages)
 
         cmd = "/usr/bin/bash -l -c '/usr/bin/rpm -Uvh --force --nodeps " + rpmFiles + "'"
         self.logger.info("VDBG-TCU-installToolChainRPMSinContainer: Installing rpms cmd: " + cmd)
         tcInstallLog = containerID.exec_run(cmd)
         # TODO: Find a way to collect exit status of the command that was run.
         if not tcInstallLog:
             self.logger.error("Installing tool chain in container failed")
             raise Exception("RPM installation in container failed")
         self.logger.info(tcInstallLog)
87815216
         self.logger.info("Successfully installed default tool-chain RPMS in container: " +
                          containerID.short_id)
7418d2bf
 
     def installCustomToolChainRPMSinContainer(self, containerID, listOfToolChainPkgs, packageName):
         self.logger.info("Installing package specific tool chain RPMs for " + packageName)
         rpmFiles = ""
         packages = ""
         for package in listOfToolChainPkgs:
             if "openjre8" in packageName or "openjdk8" in packageName:
87815216
                 rpmFile = self.findRPMFileInGivenLocation(package, constants.prevPublishXRPMRepo)
7418d2bf
             else:
87815216
                 rpmFile = self.findRPMFileInGivenLocation(package, constants.prevPublishRPMRepo)
7418d2bf
             if rpmFile is None:
87815216
                 self.logger.error("Unable to find rpm " + package +
                                   " in current and previous versions")
7418d2bf
                 raise Exception("Input Error")
             if rpmFile.find("stage/PUBLISHRPMS"):
                 rpmFile = rpmFile.replace(constants.prevPublishRPMRepo, "/publishrpms")
             if rpmFile.find("stage/PUBLISHXRPMS"):
                 rpmFile = rpmFile.replace(constants.prevPublishXRPMRepo, "/publishxrpms")
             if rpmFile.find("stage/RPMS"):
                 rpmFile = rpmFile.replace(constants.rpmPath, constants.topDirPath + "/RPMS")
             rpmFiles += " " + rpmFile
             packages += " " + package
 
         self.logger.debug("Installing rpms: " + packages)
         cmd = "rpm -Uvh --nodeps --force " + rpmFiles
87815216
         self.logger.debug("VDBG-TCU-installCustomToolChainRPMSinContainer: Installing rpms cmd: " +
                           cmd)
7418d2bf
         tcInstallLog = containerID.exec_run(cmd)
         # TODO: Find a way to collect exit status of the command that was run.
         if not tcInstallLog:
             self.logger.error("Installing tool chain in container failed")
             raise Exception("RPM installation in container failed")
         self.logger.info(tcInstallLog)
87815216
         self.logger.info("Successfully installed all tool-chain XRPMS in container: " +
                          containerID.short_id)