support/package-builder/SpecData.py
2820c61a
 import os
0f1fdc4b
 import platform
87815216
 import queue
45c9260c
 import json
 import operator
87815216
 from distutils.version import StrictVersion
 from SpecUtils import Specutils
 from Logger import Logger
45c9260c
 from constants import constants
f93ef2b0
 from StringUtils import StringUtils
 from distutils.version import LooseVersion
accc8120
 
 
5d822c2d
 class SpecObject(object):
2820c61a
     def __init__(self):
87815216
         self.listPackages = []
         self.listRPMPackages = []
         self.name = ""
         self.version = ""
         self.release = ""
f93ef2b0
         self.buildarch = {}
b3ea83b0
         self.buildRequiresAllPackages = []
87815216
         self.checkBuildRequirePackages = []
         self.installRequiresAllPackages = []
         self.installRequiresPackages = {}
         self.specFile = ""
         self.listSources = []
         self.checksums = {}
         self.listPatches = []
         self.securityHardening = ""
         self.url = ""
         self.sourceurl = ""
         self.license = ""
         self.specDefs = {}
2820c61a
 
accc8120
 
5d822c2d
 class SpecObjectsUtils(object):
5062126c
 
87815216
     def __init__(self, logPath):
5d822c2d
         self.mapSpecObjects = {}
87815216
         self.mapPackageToSpec = {}
cfd85ba2
         self.mapSpecFileNameToSpecObj = {}
26b55679
         self.logger = Logger.getLogger("Serializable Spec objects", logPath, constants.logLevel)
5062126c
 
87815216
     def readSpecsAndConvertToSerializableObjects(self, specFilesPath):
         listSpecFiles = []
         self.getListSpecFiles(listSpecFiles, specFilesPath)
2820c61a
         for specFile in listSpecFiles:
87815216
             spec = Specutils(specFile)
             specName = spec.getBasePackageName()
5d822c2d
             specObj = SpecObject()
87815216
             specObj.name = specName
b3ea83b0
             specObj.buildRequiresAllPackages = spec.getBuildRequiresAllPackages()
e45f5730
             specObj.installRequiresAllPackages = spec.getRequiresAllPackages()
             specObj.checkBuildRequirePackages = spec.getCheckBuildRequiresAllPackages()
87815216
             specObj.listPackages = spec.getPackageNames()
             specObj.specFile = specFile
             specObj.version = spec.getVersion()
             specObj.release = spec.getRelease()
             specObj.listSources = spec.getSourceNames()
             specObj.checksums = spec.getChecksums()
             specObj.specDefs = spec.getDefinitions()
             specObj.listPatches = spec.getPatchNames()
             specObj.securityHardening = spec.getSecurityHardeningOption()
             specObj.isCheckAvailable = spec.isCheckAvailable()
             specObj.license = spec.getLicense()
             specObj.url = spec.getURL()
             specObj.sourceurl = spec.getSourceURL()
2820c61a
             for specPkg in specObj.listPackages:
87815216
                 specObj.installRequiresPackages[specPkg] = spec.getRequires(specPkg)
f93ef2b0
                 specObj.buildarch[specPkg] = spec.getBuildArch(specPkg)
                 # TODO add multiversioning support
87815216
                 self.mapPackageToSpec[specPkg] = specName
adf248d5
                 if spec.getIsRPMPackage(specPkg):
                     specObj.listRPMPackages.append(specPkg)
5d822c2d
             if specName in self.mapSpecObjects:
                 self.mapSpecObjects[specName].append(specObj)
             else:
                 self.mapSpecObjects[specName]=[specObj]
cfd85ba2
             self.mapSpecFileNameToSpecObj[os.path.basename(specFile)]=specObj
5d822c2d
         for key, value in self.mapSpecObjects.items():
             if len(value) > 1:
                 self.mapSpecObjects[key] = sorted(value,
                                                   key=lambda x : self.compareVersions(x),
                                                   reverse=True)
5062126c
 
87815216
     def getListSpecFiles(self, listSpecFiles, path):
2820c61a
         for dirEntry in os.listdir(path):
             dirEntryPath = os.path.join(path, dirEntry)
87815216
             if (os.path.isfile(dirEntryPath) and
                     dirEntryPath.endswith(".spec") and
                     os.path.basename(dirEntryPath) not in
                     constants.skipSpecsForArch.get(platform.machine(), [])):
2820c61a
                 listSpecFiles.append(dirEntryPath)
             elif os.path.isdir(dirEntryPath):
87815216
                 self.getListSpecFiles(listSpecFiles, dirEntryPath)
5062126c
 
f93ef2b0
     def _getProperVersion(self,depPkg):
         if (depPkg.compare == ""):
             return self.getHighestVersion(depPkg.package)
         specObjs=self.getSpecObj(depPkg.package)
cfd85ba2
         try:
             for obj in specObjs:
f93ef2b0
                 verrel=obj.version+"-"+obj.release
                 if depPkg.compare == ">=":
cfd85ba2
                     if LooseVersion(verrel) >= LooseVersion(depPkg.version):
                         return obj.version
f93ef2b0
                 elif depPkg.compare == "<=":
cfd85ba2
                     if LooseVersion(verrel) <= LooseVersion(depPkg.version):
                         return obj.version
f93ef2b0
                 elif depPkg.compare == "=":
cfd85ba2
                     if LooseVersion(verrel) == LooseVersion(depPkg.version):
                         return obj.version
                     if LooseVersion(obj.version) == LooseVersion(depPkg.version):
                         return obj.version
f93ef2b0
                 elif depPkg.compare == "<":
cfd85ba2
                     if LooseVersion(verrel) < LooseVersion(depPkg.version):
                         return obj.version
f93ef2b0
                 elif depPkg.compare == ">":
cfd85ba2
                     if LooseVersion(verrel) > LooseVersion(depPkg.version):
                         return obj.version
         except Exception as e:
             self.logger.error("Exception happened while searching for: " + depPkg.package + depPkg.compare + depPkg.version)
             raise e
f93ef2b0
 
         # about to throw exception
         availableVersions=""
         for obj in specObjs:
             availableVersions+=" "+obj.name+"-"+obj.version+"-"+obj.release
         raise Exception("Can not find package: " + depPkg.package + depPkg.compare + depPkg.version + " available specs:"+availableVersions)
 
     def _getSpecObjField(self, package, version, field):
87815216
         specName = self.getSpecName(package)
f93ef2b0
         for specObj in self.mapSpecObjects[specName]:
             if specObj.version == version:
                 return field(specObj)
         self.logger.error("Could not able to find " + package +
                           "-" + version + " package from specs")
         raise Exception("Invalid package: " + package + "-" + version)
 
     def getBuildRequiresForPackage(self, package, version):
         buildRequiresList=[]
b3ea83b0
         buildRequiresPackages = self._getSpecObjField(package, version, field=lambda x : x.buildRequiresAllPackages)
f93ef2b0
         for pkg in buildRequiresPackages:
             properVersion = self._getProperVersion(pkg)
             buildRequiresList.append(pkg.package+"-"+properVersion)
         return buildRequiresList
 
     def getBuildRequiresForPkg(self, pkg):
         package, version = StringUtils.splitPackageNameAndVersion(pkg)
         return self.getBuildRequiresForPackage(package, version)
 
     # Returns list of [ "pkg1-vers1", "pkg2-vers2",.. ]
     def getRequiresAllForPackage(self, package, version):
         requiresList=[]
         requiresPackages = self._getSpecObjField(package, version, field=lambda x : x.installRequiresAllPackages)
         for pkg in requiresPackages:
             properVersion = self._getProperVersion(pkg)
             requiresList.append(pkg.package+"-"+properVersion)
         return requiresList
 
     def getRequiresAllForPkg(self, pkg):
         package, version = StringUtils.splitPackageNameAndVersion(pkg)
         return self.getRequiresAllForPackage(package, version)
 
     def getRequiresForPackage(self, package, version):
         requiresList=[]
87815216
         specName = self.getSpecName(package)
f93ef2b0
         for specObj in self.mapSpecObjects[specName]:
             if specObj.version == version:
                 if package in specObj.installRequiresPackages:
                     requiresPackages = specObj.installRequiresPackages[package]
                     for pkg in requiresPackages:
                         properVersion = self._getProperVersion(pkg)
                         requiresList.append(pkg.package+"-"+properVersion)
                 return requiresList
         self.logger.error("Could not able to find " + package +
                           "-" + version + " package from specs")
         raise Exception("Invalid package: " + package + "-" + version)
 
     def getRequiresForPkg(self, pkg):
         package, version = StringUtils.splitPackageNameAndVersion(pkg)
         return self.getRequiresForPackage(package, version)
 
     def getCheckBuildRequiresForPackage(self, package, version):
         checkBuildRequiresList=[]
         checkBuildRequiresPackages = self._getSpecObjField(package, version, field=lambda x : x.checkBuildRequirePackages)
         for pkg in checkBuildRequiresPackages:
             properVersion = self._getProperVersion(pkg)
             checkBuildRequiresList.append(pkg.package+"-"+properVersion)
         return checkBuildRequiresList
5f40784b
 
4a93976f
     def getSpecObj(self, package):
         specName=self.getSpecName(package)
         return self.mapSpecObjects[specName]
 
e45f5730
     def getPkgNamesFromObj(self, objlist):
         listPkgName=[]
f93ef2b0
         for name in objlist:
e45f5730
                 listPkgName.append(name.package)
         return listPkgName
 
f93ef2b0
     def getRelease(self, package, version):
         return self._getSpecObjField(package, version, field=lambda x : x.release)
5062126c
 
f93ef2b0
     def getVersions(self, package):
         versions=[]
87815216
         specName = self.getSpecName(package)
f93ef2b0
         for specObj in self.mapSpecObjects[specName]:
             versions.append(specObj.version)
         return versions
5062126c
 
f93ef2b0
     def getHighestVersion(self, package):
87815216
         specName = self.getSpecName(package)
f93ef2b0
         return self.mapSpecObjects[specName][0].version
5062126c
 
f93ef2b0
     def getBuildArch(self, package, version):
         return self._getSpecObjField(package, version, field=lambda x : x.buildarch[package])
3cc43c92
 
f93ef2b0
     def getSpecFile(self, package, version):
         return self._getSpecObjField(package, version, field=lambda x : x.specFile)
5062126c
 
f93ef2b0
     def getPatches(self, package, version):
         return self._getSpecObjField(package, version, field=lambda x : x.listPatches)
3cc43c92
 
f93ef2b0
     def getSources(self, package, version):
         return self._getSpecObjField(package, version, field=lambda x : x.listSources)
37022ec3
 
f93ef2b0
     def getSHA1(self, package, version, source):
         return self._getSpecObjField(package, version, field=lambda x : x.checksums.get(source))
 
     # returns list of package names (no versions)
     def getPackages(self, package, version):
         return self._getSpecObjField(package, version, field=lambda x : x.listPackages)
 
     def getPackagesForPkg(self, pkg):
29d834bc
         pkgs=[]
f93ef2b0
         package, version = StringUtils.splitPackageNameAndVersion(pkg)
29d834bc
         for p in self.getPackages(package, version):
             pkgs.append(p+"-"+version)
         return pkgs
f93ef2b0
 
     def getRPMPackages(self, package, version):
         return self._getSpecObjField(package, version, field=lambda x : x.listRPMPackages)
adf248d5
 
accc8120
     @staticmethod
5d822c2d
     def compareVersions(p):
         return (StrictVersion(p.version))
87815216
 
     def getSpecName(self, package):
         if package in self.mapPackageToSpec:
             specName = self.mapPackageToSpec[package]
5d822c2d
             if specName in self.mapSpecObjects:
51e6babb
                 return specName
26b55679
         self.logger.error("Could not find " + package + " package from specs")
87815216
         raise Exception("Invalid package:" + package)
b5e09fac
 
87815216
     def isRPMPackage(self, package):
         if package in self.mapPackageToSpec:
             specName = self.mapPackageToSpec[package]
5d822c2d
             if specName in self.mapSpecObjects:
af3575c9
                 return True
         return False
b5e09fac
 
f93ef2b0
     def getSecurityHardeningOption(self, package, version):
         return self._getSpecObjField(package, version, field=lambda x : x.securityHardening)
cb4e8710
 
f93ef2b0
     def isCheckAvailable(self, package, version):
         return self._getSpecObjField(package, version, field=lambda x : x.isCheckAvailable)
b5e09fac
 
97a9151c
     def getListPackages(self):
5d822c2d
         return list(self.mapSpecObjects.keys())
5062126c
 
f93ef2b0
     def getURL(self, package, version):
         return self._getSpecObjField(package, version, field=lambda x : x.url)
5062126c
 
f93ef2b0
     def getSourceURL(self, package, version):
         return self._getSpecObjField(package, version, field=lambda x : x.sourceurl)
5062126c
 
f93ef2b0
     def getLicense(self, package, version):
         return self._getSpecObjField(package, version, field=lambda x : x.license)
 
     # Converts "glibc-devel-2.28" into "glibc-2.28"
     def getBasePkg(self, pkg):
         package, version = StringUtils.splitPackageNameAndVersion(pkg)
         return self.getSpecName(package)+"-"+version
5d822c2d
 
5062126c
 
2820c61a
     def printAllObjects(self):
5d822c2d
         listSpecs = self.mapSpecObjects.keys()
2820c61a
         for spec in listSpecs:
cfd85ba2
             for specObj in self.mapSpecObjects[spec]:
26b55679
                 self.logger.debug("-----------Spec:"+specObj.name+"--------------")
                 self.logger.debug("Version:"+specObj.version)
                 self.logger.debug("Release:"+specObj.release)
                 self.logger.debug("SpecFile:"+specObj.specFile)
                 self.logger.debug("Source Files")
                 self.logger.debug(specObj.listSources)
                 self.logger.debug("Patch Files")
                 self.logger.debug(specObj.listPatches)
                 self.logger.debug("List RPM packages")
                 self.logger.debug(specObj.listPackages)
                 self.logger.debug("Build require packages")
b3ea83b0
                 self.logger.debug(self.getPkgNamesFromObj(specObj.buildRequiresAllPackages))
26b55679
                 self.logger.debug("install require packages")
                 self.logger.debug(self.getPkgNamesFromObj(specObj.installRequiresAllPackages))
                 self.logger.debug(specObj.installRequiresPackages)
                 self.logger.debug("security_hardening: " + specObj.securityHardening)
                 self.logger.debug("------------------------------------------------")
5e29a499
 
accc8120
 
45c9260c
 class SPECS(object):
     __instance = None
     specData = None
 
     @staticmethod
     def getData():
         """ Static access method. """
87815216
         if SPECS.__instance is None:
45c9260c
             SPECS()
         return SPECS.__instance.specData
 
     def __init__(self):
         """ Virtually private constructor. """
87815216
         if SPECS.__instance is not None:
45c9260c
             raise Exception("This class is a singleton!")
         else:
             SPECS.__instance = self
         self.initialize()
 
     def initialize(self):
343d89e8
         # Preparse some files
accc8120
         # adding openjre8 version rpm macro
87815216
         if platform.machine() == "x86_64":
343d89e8
             spec = Specutils(constants.specPath + "/openjdk8/openjdk8.spec")
7e05c54b
         else:
             spec = Specutils(constants.specPath + "/openjdk8/openjdk8_aarch64.spec")
         java8version = spec.getVersion()
87815216
         constants.addMacro("JAVA8_VERSION", java8version)
343d89e8
 
a0abf4dd
         # adding openjre9 version rpm macro
         if platform.machine() == "x86_64":
             spec = Specutils(constants.specPath + "/openjdk9/openjdk9.spec")
             java9version = spec.getVersion()
             constants.addMacro("JAVA9_VERSION", java9version)
 
 
         # adding openjre10 version rpm macro
         if platform.machine() == "x86_64":
             spec = Specutils(constants.specPath + "/openjdk10/openjdk10.spec")
             java10version = spec.getVersion()
             constants.addMacro("JAVA10_VERSION", java10version)
 
accc8120
         # adding kernelversion rpm macro
343d89e8
         spec = Specutils(constants.specPath + "/linux/linux.spec")
         kernelversion = spec.getVersion()
87815216
         constants.addMacro("KERNEL_VERSION", kernelversion)
45c9260c
 
accc8120
         # adding kernelrelease rpm macro
343d89e8
         kernelrelease = spec.getRelease()
87815216
         constants.addMacro("KERNEL_RELEASE", kernelrelease)
45c9260c
 
accc8120
         # adding kernelsubrelease rpm macro
87815216
         a, b, c = kernelversion.split(".")
         kernelsubrelease = ('%02d%02d%03d%03d' % (int(a),
                                                   int(b), int(c),
                                                   int(kernelrelease.split('.')[0])))
45c9260c
         if kernelsubrelease:
87815216
             kernelsubrelease = "." + kernelsubrelease
             constants.addMacro("kernelsubrelease", kernelsubrelease)
45c9260c
 
343d89e8
         # Full parsing
5d822c2d
         self.specData = SpecObjectsUtils(constants.logPath)
343d89e8
         self.specData.readSpecsAndConvertToSerializableObjects(constants.specPath)
45c9260c