Browse code

multiversion support in package builder.

Change-Id: Idc8a3063fcd0237a554fd2c2eaac60b2dc9f45c4
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/4990
Tested-by: gerrit-photon <photon-checkins@vmware.com>
Reviewed-by: Sharath George

Xiaolin Li authored on 2018/04/11 08:58:03
Showing 3 changed files
... ...
@@ -24,12 +24,16 @@ class PackageBuilderBase(object):
24 24
 
25 25
     def buildPackageFunction(self, package):
26 26
         self._buildPackagePrepareFunction(package)
27
-        try:
28
-            self._buildPackage()
29
-        except Exception as e:
30
-            # TODO: self.logger might be None
31
-            self.logger.exception(e)
32
-            raise e
27
+        versions = self.getNumOfVersions(package)
28
+        if(versions < 1):
29
+            raise Exception("No package exists")
30
+        for version in range(0, versions):
31
+            try:
32
+                self._buildPackage(version)
33
+            except Exception as e:
34
+                # TODO: self.logger might be None
35
+                self.logger.exception(e)
36
+                raise e
33 37
 
34 38
     def _buildPackagePrepareFunction(self, package):
35 39
         self.package = package
... ...
@@ -66,25 +70,25 @@ class PackageBuilderBase(object):
66 66
                 listInstalledPackages.append(packageName)
67 67
         return listInstalledPackages, listInstalledRPMs
68 68
 
69
-    def _checkIfPackageIsAlreadyBuilt(self):
69
+    def _checkIfPackageIsAlreadyBuilt(self, index=0):
70 70
         basePkg = SPECS.getData().getSpecName(self.package)
71
-        listRPMPackages = SPECS.getData().getRPMPackages(basePkg)
71
+        listRPMPackages = SPECS.getData().getRPMPackages(basePkg, index)
72 72
         packageIsAlreadyBuilt = True
73 73
         pkgUtils = PackageUtils(self.logName, self.logPath)
74 74
         for pkg in listRPMPackages:
75
-            if pkgUtils.findRPMFileForGivenPackage(pkg) is None:
75
+            if pkgUtils.findRPMFileForGivenPackage(pkg, index) is None:
76 76
                 packageIsAlreadyBuilt = False
77 77
                 break
78 78
         return packageIsAlreadyBuilt
79 79
 
80
-    def _findRunTimeRequiredRPMPackages(self, rpmPackage):
81
-        return SPECS.getData().getRequiresForPackage(rpmPackage)
80
+    def _findRunTimeRequiredRPMPackages(self, rpmPackage, index=0):
81
+        return SPECS.getData().getRequiresForPackage(rpmPackage, index)
82 82
 
83
-    def _findBuildTimeRequiredPackages(self):
84
-        return SPECS.getData().getBuildRequiresForPackage(self.package)
83
+    def _findBuildTimeRequiredPackages(self, index=0):
84
+        return SPECS.getData().getBuildRequiresForPackage(self.package, index)
85 85
 
86
-    def _findBuildTimeCheckRequiredPackages(self):
87
-        return SPECS.getData().getCheckBuildRequiresForPackage(self.package)
86
+    def _findBuildTimeCheckRequiredPackages(self, index=0):
87
+        return SPECS.getData().getCheckBuildRequiresForPackage(self.package, index)
88 88
 
89 89
     def _installPackage(self, pkgUtils, package, instanceID, destLogPath,
90 90
                         listInstalledPackages, listInstalledRPMs):
... ...
@@ -121,12 +125,12 @@ class PackageBuilderBase(object):
121 121
                 self._installPackage(pkgUtils, pkg, instanceID, destLogPath,
122 122
                                      listInstalledPackages, listInstalledRPMs)
123 123
 
124
-    def _findDependentPackagesAndInstalledRPM(self, instanceID):
124
+    def _findDependentPackagesAndInstalledRPM(self, instanceID, index=0):
125 125
         listInstalledPackages, listInstalledRPMs = self._findInstalledPackages(instanceID)
126 126
         self.logger.info(listInstalledPackages)
127
-        listDependentPackages = self._findBuildTimeRequiredPackages()
127
+        listDependentPackages = self._findBuildTimeRequiredPackages(index)
128 128
         if constants.rpmCheck and self.package in constants.testForceRPMS:
129
-            listDependentPackages.extend(self._findBuildTimeCheckRequiredPackages())
129
+            listDependentPackages.extend(self._findBuildTimeCheckRequiredPackages(index))
130 130
             testPackages = (set(constants.listMakeCheckRPMPkgtoInstall) -
131 131
                             set(listInstalledPackages) -
132 132
                             set([self.package]))
... ...
@@ -134,6 +138,9 @@ class PackageBuilderBase(object):
134 134
             listDependentPackages = list(set(listDependentPackages))
135 135
         return listDependentPackages, listInstalledPackages, listInstalledRPMs
136 136
 
137
+    @staticmethod
138
+    def getNumOfVersions(package):
139
+        return SPECS.getData().getNumberOfVersions(package)
137 140
 
138 141
 class PackageBuilderContainer(PackageBuilderBase):
139 142
     def __init__(self, mapPackageToCycles, pkgBuildType):
... ...
@@ -210,11 +217,11 @@ class PackageBuilderContainer(PackageBuilderBase):
210 210
             raise e
211 211
         return containerID, chrootID
212 212
 
213
-    def _buildPackage(self):
213
+    def _buildPackage(self, index=0):
214 214
         #do not build if RPM is already built
215 215
         #test only if the package is in the testForceRPMS with rpmCheck
216 216
         #build only if the package is not in the testForceRPMS with rpmCheck
217
-        if self._checkIfPackageIsAlreadyBuilt():
217
+        if self._checkIfPackageIsAlreadyBuilt(index):
218 218
             if not constants.rpmCheck:
219 219
                 self.logger.info("Skipping building the package:" + self.package)
220 220
                 return
... ...
@@ -243,7 +250,7 @@ class PackageBuilderContainer(PackageBuilderBase):
243 243
                     self.package)
244 244
 
245 245
             listDependentPackages, listInstalledPackages, listInstalledRPMs = (
246
-                self._findDependentPackagesAndInstalledRPM(containerID))
246
+                self._findDependentPackagesAndInstalledRPM(containerID, index))
247 247
 
248 248
             pkgUtils = PackageUtils(self.logName, self.logPath)
249 249
             if listDependentPackages:
... ...
@@ -258,11 +265,12 @@ class PackageBuilderContainer(PackageBuilderBase):
258 258
 
259 259
             self.logger.info("BuildContainer-buildPackage: Start building the package: " +
260 260
                              self.package)
261
-            pkgUtils.adjustGCCSpecsInContainer(self.package, containerID, destLogPath)
261
+            pkgUtils.adjustGCCSpecsInContainer(self.package, containerID, destLogPath, index)
262 262
             pkgUtils.buildRPMSForGivenPackageInContainer(
263 263
                 self.package,
264 264
                 containerID,
265
-                destLogPath)
265
+                destLogPath,
266
+                index)
266 267
             self.logger.info("BuildContainer-buildPackage: Successfully built the package: " +
267 268
                              self.package)
268 269
         except Exception as e:
... ...
@@ -305,11 +313,11 @@ class PackageBuilderChroot(PackageBuilderBase):
305 305
             raise e
306 306
         return chrootID
307 307
 
308
-    def _buildPackage(self):
308
+    def _buildPackage(self, index=0):
309 309
         #do not build if RPM is already built
310 310
         #test only if the package is in the testForceRPMS with rpmCheck
311 311
         #build only if the package is not in the testForceRPMS with rpmCheck
312
-        if self._checkIfPackageIsAlreadyBuilt():
312
+        if self._checkIfPackageIsAlreadyBuilt(index):
313 313
             if not constants.rpmCheck:
314 314
                 self.logger.info("Skipping building the package:" + self.package)
315 315
                 return
... ...
@@ -322,9 +330,10 @@ class PackageBuilderChroot(PackageBuilderBase):
322 322
         try:
323 323
             chrootID = self._prepareBuildRoot()
324 324
             listDependentPackages, listInstalledPackages, listInstalledRPMs = (
325
-                self._findDependentPackagesAndInstalledRPM(chrootID))
325
+                self._findDependentPackagesAndInstalledRPM(chrootID, index))
326 326
 
327 327
             pkgUtils = PackageUtils(self.logName, self.logPath)
328
+
328 329
             if listDependentPackages:
329 330
                 self.logger.info("Installing the build time dependent packages......")
330 331
                 for pkg in listDependentPackages:
... ...
@@ -333,9 +342,9 @@ class PackageBuilderChroot(PackageBuilderBase):
333 333
                 pkgUtils.installRPMSInAOneShot(chrootID, self.logPath)
334 334
                 self.logger.info("Finished installing the build time dependent packages....")
335 335
 
336
-            pkgUtils.adjustGCCSpecs(self.package, chrootID, self.logPath)
336
+            pkgUtils.adjustGCCSpecs(self.package, chrootID, self.logPath, index)
337 337
             pkgUtils.buildRPMSForGivenPackage(self.package, chrootID,
338
-                                              self.logPath)
338
+                                              self.logPath, index)
339 339
             self.logger.info("Successfully built the package:" + self.package)
340 340
         except Exception as e:
341 341
             self.logger.error("Failed while building package:" + self.package)
... ...
@@ -84,12 +84,12 @@ class PackageUtils(object):
84 84
                 self.logger.error("Unable to install rpms")
85 85
                 raise Exception("RPM installation failed")
86 86
 
87
-    def buildRPMSForGivenPackage(self, package, chrootID, destLogPath=None):
87
+    def buildRPMSForGivenPackage(self, package, chrootID, destLogPath=None, index=0):
88 88
         self.logger.info("Building rpm's for package:" + package)
89 89
 
90
-        listSourcesFiles = SPECS.getData().getSources(package)
91
-        listPatchFiles = SPECS.getData().getPatches(package)
92
-        specFile = SPECS.getData().getSpecFile(package)
90
+        listSourcesFiles = SPECS.getData().getSources(package, index)
91
+        listPatchFiles = SPECS.getData().getPatches(package, index)
92
+        specFile = SPECS.getData().getSpecFile(package, index)
93 93
         specName = SPECS.getData().getSpecName(package) + ".spec"
94 94
 
95 95
         chrootSourcePath = chrootID + constants.topDirPath + "/SOURCES/"
... ...
@@ -100,8 +100,8 @@ class PackageUtils(object):
100 100
 
101 101
         # FIXME: some sources are located in SPECS/.. how to mount?
102 102
         #        if os.geteuid()==0:
103
-        self._copySourcesTobuildroot(listSourcesFiles, package, chrootSourcePath)
104
-        self._copySourcesTobuildroot(listPatchFiles, package, chrootSourcePath)
103
+        self._copySourcesTobuildroot(listSourcesFiles, package, chrootSourcePath, index)
104
+        self._copySourcesTobuildroot(listPatchFiles, package, chrootSourcePath, index)
105 105
         macros = []
106 106
 
107 107
         listAdditionalFiles, macros = self._getAdditionalBuildFiles(package)
... ...
@@ -143,10 +143,10 @@ class PackageUtils(object):
143 143
         for srpmFile in listSRPMFiles:
144 144
             srpmDestFile = self._copyRPM(chrootID + "/" + srpmFile, constants.sourceRpmPath)
145 145
 
146
-    def findRPMFileForGivenPackage(self, package):
146
+    def findRPMFileForGivenPackage(self, package, index=0):
147 147
         cmdUtils = CommandUtils()
148
-        version = SPECS.getData().getVersion(package)
149
-        release = SPECS.getData().getRelease(package)
148
+        version = SPECS.getData().getVersion(package, index)
149
+        release = SPECS.getData().getRelease(package, index)
150 150
         listFoundRPMFiles = sum([cmdUtils.findFile(package + "-" + version + "-" + release + "." +
151 151
                                                    platform.machine()+".rpm",
152 152
                                                    constants.rpmPath),
... ...
@@ -195,8 +195,8 @@ class PackageUtils(object):
195 195
             return result.decode().split()
196 196
         return result
197 197
 
198
-    def adjustGCCSpecs(self, package, chrootID, logPath):
199
-        opt = " " + SPECS.getData().getSecurityHardeningOption(package)
198
+    def adjustGCCSpecs(self, package, chrootID, logPath, index=0):
199
+        opt = " " + SPECS.getData().getSecurityHardeningOption(package, index)
200 200
         cmdUtils = CommandUtils()
201 201
         cpcmd = ("cp " + self.adjustGCCSpecScript + " " + chrootID +
202 202
                  "/tmp/" + self.adjustGCCSpecScript)
... ...
@@ -313,8 +313,8 @@ class PackageUtils(object):
313 313
             return result.decode().split()
314 314
         return result
315 315
 
316
-    def adjustGCCSpecsInContainer(self, package, containerID, logPath):
317
-        opt = " " + SPECS.getData().getSecurityHardeningOption(package)
316
+    def adjustGCCSpecsInContainer(self, package, containerID, logPath, index=0):
317
+        opt = " " + SPECS.getData().getSecurityHardeningOption(package, index)
318 318
         adjustCmd = "/" + self.adjustGCCSpecScript + opt
319 319
         adjustCmd = "/bin/bash -l -c '" + adjustCmd + "'"
320 320
         logFile = logPath + "/adjustGCCSpecScript.log"
... ...
@@ -332,13 +332,13 @@ class PackageUtils(object):
332 332
         self.logger.error("Failed while adjusting gcc specs")
333 333
         raise Exception("Failed while adjusting gcc specs")
334 334
 
335
-    def buildRPMSForGivenPackageInContainer(self, package, containerID, destLogPath=None):
335
+    def buildRPMSForGivenPackageInContainer(self, package, containerID, destLogPath=None, index=0):
336 336
         self.logger.info("Building rpm's for package " + package + " in container " +
337 337
                          containerID.short_id)
338 338
 
339
-        listSourcesFiles = SPECS.getData().getSources(package)
340
-        listPatchFiles = SPECS.getData().getPatches(package)
341
-        specFile = SPECS.getData().getSpecFile(package)
339
+        listSourcesFiles = SPECS.getData().getSources(package, index)
340
+        listPatchFiles = SPECS.getData().getPatches(package, index)
341
+        specFile = SPECS.getData().getSpecFile(package, index)
342 342
         specName = SPECS.getData().getSpecName(package) + ".spec"
343 343
         sourcePath = constants.topDirPath + "/SOURCES/"
344 344
         specPath = constants.topDirPath + "/SPECS/"
... ...
@@ -358,9 +358,9 @@ class PackageUtils(object):
358 358
         #        if os.geteuid()==0:
359 359
         #TODO: mount it in, don't copy
360 360
         macros = []
361
-        self._copySourcesToContainer(listSourcesFiles, package, containerID, sourcePath)
361
+        self._copySourcesToContainer(listSourcesFiles, package, containerID, sourcePath, index)
362 362
         #TODO: mount it in, don't copy
363
-        self._copySourcesToContainer(listPatchFiles, package, containerID, sourcePath)
363
+        self._copySourcesToContainer(listPatchFiles, package, containerID, sourcePath, index)
364 364
         listAdditionalFiles, macros = self._getAdditionalBuildFiles(package)
365 365
         self._copyAdditionalBuildFilesToContainer(listAdditionalFiles, containerID)
366 366
 
... ...
@@ -389,7 +389,7 @@ class PackageUtils(object):
389 389
                 rpmLog = destLogPath + "/" + package + ".log"
390 390
                 if (constants.rpmCheck and
391 391
                         package in constants.testForceRPMS and
392
-                        SPECS.getData().isCheckAvailable(package)):
392
+                        SPECS.getData().isCheckAvailable(package, index)):
393 393
                     cmd = "sed -i '/^Executing(%check):/,/^Processing files:/{//!b};d' " + rpmLog
394 394
                     logFile = destLogPath + "/adjustTestFile.log"
395 395
                     returnVal = CommandUtils().runCommandInShell(cmd, logFile)
... ...
@@ -445,10 +445,10 @@ class PackageUtils(object):
445 445
             shutil.move(rpmDestPathTemp, rpmDestPath)
446 446
         return rpmDestPath
447 447
 
448
-    def _verifyShaAndGetSourcePath(self, source, package):
448
+    def _verifyShaAndGetSourcePath(self, source, package, index=0):
449 449
         cmdUtils = CommandUtils()
450 450
         # Fetch/verify sources if sha1 not None.
451
-        sha1 = SPECS.getData().getSHA1(package, source)
451
+        sha1 = SPECS.getData().getSHA1(package, source, index)
452 452
         if sha1 is not None:
453 453
             PullSources.get(source, sha1, constants.sourcePath, constants.pullsourcesConfig,
454 454
                             self.logger)
... ...
@@ -474,9 +474,9 @@ class PackageUtils(object):
474 474
             raise Exception("Multiple sources found")
475 475
         return sourcePath
476 476
 
477
-    def _copySourcesTobuildroot(self, listSourceFiles, package, destDir):
477
+    def _copySourcesTobuildroot(self, listSourceFiles, package, destDir, index=0):
478 478
         for source in listSourceFiles:
479
-            sourcePath = self._verifyShaAndGetSourcePath(source, package)
479
+            sourcePath = self._verifyShaAndGetSourcePath(source, package, index)
480 480
             self.logger.info("Copying... Source path :" + source +
481 481
                              " Source filename: " + sourcePath[0])
482 482
             shutil.copy2(sourcePath[0], destDir)
... ...
@@ -571,10 +571,10 @@ class PackageUtils(object):
571 571
         return listRPMFiles, listSRPMFiles
572 572
 
573 573
 
574
-    def _copySourcesToContainer(self, listSourceFiles, package, containerID, destDir):
574
+    def _copySourcesToContainer(self, listSourceFiles, package, containerID, destDir, index=0):
575 575
         cmdUtils = CommandUtils()
576 576
         for source in listSourceFiles:
577
-            sourcePath = self._verifyShaAndGetSourcePath(source, package)
577
+            sourcePath = self._verifyShaAndGetSourcePath(source, package, index)
578 578
             self.logger.info("Copying source file: " + sourcePath[0])
579 579
             copyCmd = "docker cp " + sourcePath[0] + " " + containerID.short_id + ":" + destDir
580 580
             cmdUtils.runCommandInShell(copyCmd)
... ...
@@ -624,7 +624,7 @@ class PackageUtils(object):
624 624
 
625 625
         if constants.rpmCheck and package in constants.testForceRPMS:
626 626
             self.logger.info("#" * (68 + 2 * len(package)))
627
-            if not SPECS.getData().isCheckAvailable(package):
627
+            if not SPECS.getData().isCheckAvailable(package, index):
628 628
                 self.logger.info("####### " + package +
629 629
                                  " MakeCheck is not available. Skipping MakeCheck TEST for " +
630 630
                                  package + " #######")
... ...
@@ -656,7 +656,7 @@ class PackageUtils(object):
656 656
             raise Exception("RPM Build failed")
657 657
 
658 658
         if constants.rpmCheck and package in constants.testForceRPMS:
659
-            if not SPECS.getData().isCheckAvailable(package):
659
+            if not SPECS.getData().isCheckAvailable(package, index):
660 660
                 constants.testLogger.info(package + " : N/A")
661 661
             elif returnVal:
662 662
                 constants.testLogger.info(package + " : PASS")
... ...
@@ -10,7 +10,7 @@ from constants import constants
10 10
 
11 11
 
12 12
 
13
-class SerializableSpecObject(object):
13
+class SpecObject(object):
14 14
     def __init__(self):
15 15
         self.listPackages = []
16 16
         self.listRPMPackages = []
... ...
@@ -32,10 +32,10 @@ class SerializableSpecObject(object):
32 32
         self.specDefs = {}
33 33
 
34 34
 
35
-class SerializableSpecObjectsUtils(object):
35
+class SpecObjectsUtils(object):
36 36
 
37 37
     def __init__(self, logPath):
38
-        self.mapSerializableSpecObjects = {}
38
+        self.mapSpecObjects = {}
39 39
         self.mapPackageToSpec = {}
40 40
         self.logger = Logger.getLogger("Serializable Spec objects", logPath)
41 41
 
... ...
@@ -43,10 +43,9 @@ class SerializableSpecObjectsUtils(object):
43 43
         listSpecFiles = []
44 44
         self.getListSpecFiles(listSpecFiles, specFilesPath)
45 45
         for specFile in listSpecFiles:
46
-            skipUpdating = False
47 46
             spec = Specutils(specFile)
48 47
             specName = spec.getBasePackageName()
49
-            specObj = SerializableSpecObject()
48
+            specObj = SpecObject()
50 49
             specObj.name = specName
51 50
             specObj.buildRequirePackages = spec.getBuildRequiresAllPackages()
52 51
             specObj.installRequiresAllPackages = spec.getRequiresAllPackages()
... ...
@@ -65,17 +64,19 @@ class SerializableSpecObjectsUtils(object):
65 65
             specObj.url = spec.getURL()
66 66
             specObj.sourceurl = spec.getSourceURL()
67 67
             for specPkg in specObj.listPackages:
68
-                if specPkg in self.mapPackageToSpec:
69
-                    existingObj = self.mapSerializableSpecObjects[self.mapPackageToSpec[specPkg]]
70
-                    if self.compareVersions(existingObj, specObj) == 1:
71
-                        skipUpdating = True
72
-                        break
73 68
                 specObj.installRequiresPackages[specPkg] = spec.getRequires(specPkg)
74 69
                 self.mapPackageToSpec[specPkg] = specName
75 70
                 if spec.getIsRPMPackage(specPkg):
76 71
                     specObj.listRPMPackages.append(specPkg)
77
-            if not skipUpdating:
78
-                self.mapSerializableSpecObjects[specName] = specObj
72
+            if specName in self.mapSpecObjects:
73
+                self.mapSpecObjects[specName].append(specObj)
74
+            else:
75
+                self.mapSpecObjects[specName]=[specObj]
76
+        for key, value in self.mapSpecObjects.items():
77
+            if len(value) > 1:
78
+                self.mapSpecObjects[key] = sorted(value,
79
+                                                  key=lambda x : self.compareVersions(x),
80
+                                                  reverse=True)
79 81
 
80 82
     def getListSpecFiles(self, listSpecFiles, path):
81 83
         for dirEntry in os.listdir(path):
... ...
@@ -88,80 +89,64 @@ class SerializableSpecObjectsUtils(object):
88 88
             elif os.path.isdir(dirEntryPath):
89 89
                 self.getListSpecFiles(listSpecFiles, dirEntryPath)
90 90
 
91
-    def getBuildRequiresForPackage(self, package):
91
+    def getBuildRequiresForPackage(self, package, index=0):
92 92
         specName = self.getSpecName(package)
93
-        return self.mapSerializableSpecObjects[specName].buildRequirePackages
93
+        return self.mapSpecObjects[specName][index].buildRequirePackages
94 94
 
95
-    def getRequiresAllForPackage(self, package):
95
+    def getRequiresAllForPackage(self, package, index=0):
96 96
         specName = self.getSpecName(package)
97
-        return self.mapSerializableSpecObjects[specName].installRequiresAllPackages
97
+        return self.mapSpecObjects[specName][index].installRequiresAllPackages
98 98
 
99
-    def getRequiresForPackage(self, package):
99
+    def getRequiresForPackage(self, package, index=0):
100 100
         specName = self.getSpecName(package)
101
-        if package in self.mapSerializableSpecObjects[specName].installRequiresPackages:
102
-            return self.mapSerializableSpecObjects[specName].installRequiresPackages[package]
101
+        if package in self.mapSpecObjects[specName][index].installRequiresPackages:
102
+            return self.mapSpecObjects[specName][index].installRequiresPackages[package]
103 103
         return None
104 104
 
105
-    def getCheckBuildRequiresForPackage(self, package):
105
+    def getCheckBuildRequiresForPackage(self, package, index=0):
106 106
         specName = self.getSpecName(package)
107
-        return self.mapSerializableSpecObjects[specName].checkBuildRequirePackages
107
+        return self.mapSpecObjects[specName][index].checkBuildRequirePackages
108 108
 
109
-    def getRelease(self, package):
109
+    def getRelease(self, package, index=0):
110 110
         specName = self.getSpecName(package)
111
-        return self.mapSerializableSpecObjects[specName].release
111
+        return self.mapSpecObjects[specName][index].release
112 112
 
113
-    def getVersion(self, package):
113
+    def getVersion(self, package, index=0):
114 114
         specName = self.getSpecName(package)
115
-        return self.mapSerializableSpecObjects[specName].version
115
+        return self.mapSpecObjects[specName][index].version
116 116
 
117
-    def getSpecFile(self, package):
117
+    def getSpecFile(self, package, index=0):
118 118
         specName = self.getSpecName(package)
119
-        return self.mapSerializableSpecObjects[specName].specFile
119
+        return self.mapSpecObjects[specName][index].specFile
120 120
 
121
-    def getPatches(self, package):
121
+    def getPatches(self, package, index=0):
122 122
         specName = self.getSpecName(package)
123
-        return self.mapSerializableSpecObjects[specName].listPatches
123
+        return self.mapSpecObjects[specName][index].listPatches
124 124
 
125
-    def getSources(self, package):
125
+    def getSources(self, package, index=0):
126 126
         specName = self.getSpecName(package)
127
-        return self.mapSerializableSpecObjects[specName].listSources
127
+        return self.mapSpecObjects[specName][index].listSources
128 128
 
129
-    def getSHA1(self, package, source):
129
+    def getSHA1(self, package, source, index=0):
130 130
         specName = self.getSpecName(package)
131
-        return self.mapSerializableSpecObjects[specName].checksums.get(source)
131
+        return self.mapSpecObjects[specName][index].checksums.get(source)
132 132
 
133
-    def getPackages(self, package):
133
+    def getPackages(self, package, index=0):
134 134
         specName = self.getSpecName(package)
135
-        return self.mapSerializableSpecObjects[specName].listPackages
135
+        return self.mapSpecObjects[specName][index].listPackages
136 136
 
137
-    def getRPMPackages(self, package):
137
+    def getRPMPackages(self, package, index=0):
138 138
         specName = self.getSpecName(package)
139
-        return self.mapSerializableSpecObjects[specName].listRPMPackages
139
+        return self.mapSpecObjects[specName][index].listRPMPackages
140 140
 
141 141
     @staticmethod
142
-    def getReleaseNum(releaseVal):
143
-        releaseNum = releaseVal.find("%")
144
-        if releaseNum != -1:
145
-            return releaseVal[0:releaseNum]
146
-        else:
147
-            return releaseVal
148
-
149
-    def compareVersions(self, existingObj, newObject):
150
-        if StrictVersion(existingObj.version) > StrictVersion(newObject.version):
151
-            return 1
152
-        elif StrictVersion(existingObj.version) < StrictVersion(newObject.version):
153
-            return -1
154
-        else:
155
-            if (int(self.getReleaseNum(existingObj.release)) >
156
-                    int(self.getReleaseNum(newObject.release))):
157
-                return 1
158
-            else:
159
-                return -1
142
+    def compareVersions(p):
143
+        return (StrictVersion(p.version))
160 144
 
161 145
     def getSpecName(self, package):
162 146
         if package in self.mapPackageToSpec:
163 147
             specName = self.mapPackageToSpec[package]
164
-            if specName in self.mapSerializableSpecObjects:
148
+            if specName in self.mapSpecObjects:
165 149
                 return specName
166 150
         self.logger.error("Could not able to find " + package + " package from specs")
167 151
         raise Exception("Invalid package:" + package)
... ...
@@ -169,37 +154,41 @@ class SerializableSpecObjectsUtils(object):
169 169
     def isRPMPackage(self, package):
170 170
         if package in self.mapPackageToSpec:
171 171
             specName = self.mapPackageToSpec[package]
172
-            if specName in self.mapSerializableSpecObjects:
172
+            if specName in self.mapSpecObjects:
173 173
                 return True
174 174
         return False
175 175
 
176
-    def getSecurityHardeningOption(self, package):
176
+    def getSecurityHardeningOption(self, package, index=0):
177 177
         specName = self.getSpecName(package)
178
-        return self.mapSerializableSpecObjects[specName].securityHardening
178
+        return self.mapSpecObjects[specName][index].securityHardening
179 179
 
180
-    def isCheckAvailable(self, package):
180
+    def isCheckAvailable(self, package, index=0):
181 181
         specName = self.getSpecName(package)
182
-        return self.mapSerializableSpecObjects[specName].isCheckAvailable
182
+        return self.mapSpecObjects[specName][index].isCheckAvailable
183 183
 
184 184
     def getListPackages(self):
185
-        return list(self.mapSerializableSpecObjects.keys())
185
+        return list(self.mapSpecObjects.keys())
186 186
 
187
-    def getURL(self, package):
187
+    def getURL(self, package, index=0):
188 188
         specName = self.getSpecName(package)
189
-        return self.mapSerializableSpecObjects[specName].url
189
+        return self.mapSpecObjects[specName][index].url
190 190
 
191
-    def getSourceURL(self, package):
191
+    def getSourceURL(self, package, index=0):
192 192
         specName = self.getSpecName(package)
193
-        return self.mapSerializableSpecObjects[specName].sourceurl
193
+        return self.mapSpecObjects[specName][index].sourceurl
194 194
 
195
-    def getLicense(self, package):
195
+    def getLicense(self, package, index=0):
196 196
         specName = self.getSpecName(package)
197
-        return self.mapSerializableSpecObjects[specName].license
197
+        return self.mapSpecObjects[specName][index].license
198
+
199
+    def getNumberOfVersions(self, package):
200
+        specName=self.getSpecName(package)
201
+        return len(self.mapSpecObjects[specName])
198 202
 
199 203
     def printAllObjects(self):
200
-        listSpecs = self.mapSerializableSpecObjects.keys()
204
+        listSpecs = self.mapSpecObjects.keys()
201 205
         for spec in listSpecs:
202
-            specObj = self.mapSerializableSpecObjects[spec]
206
+            specObj = self.mapSpecObjects[spec]
203 207
             self.logger.info("-----------Spec:"+specObj.name+"--------------")
204 208
             self.logger.info("Version:"+specObj.version)
205 209
             self.logger.info("Release:"+specObj.release)
... ...
@@ -276,7 +265,7 @@ class SPECS(object):
276 276
             constants.addMacro("kernelsubrelease", kernelsubrelease)
277 277
 
278 278
         # Full parsing
279
-        self.specData = SerializableSpecObjectsUtils(constants.logPath)
279
+        self.specData = SpecObjectsUtils(constants.logPath)
280 280
         self.specData.readSpecsAndConvertToSerializableObjects(constants.specPath)
281 281
 
282 282