Browse code

linux: support for KAT builds

For FIPS 140 certification.
To use it add KAT_BUILD=<kat number> to the make invocation.
Valid kat numbers are: kat01, kat02, ... kat09, kat10.
Example: make packages KAT_BUILD=kat07

Extras:
Redesign and improvements in the package builder:
- Improved macros parsing. Support for %{?var:1} and %{?var:text %var}.
- Support for %if conditional block. (TODO: %if %{with_check} should be
handled as generic %if case).
- Move macros parsing to SpecParser.
- Handle macros only once - at parse time.
- Keep spec define macros only in spec class.

Change-Id: I9836b969a143e5604c2212ee93bb9b566c9b3ff3
Reviewed-on: http://photon-jenkins.eng.vmware.com:8082/4508
Tested-by: gerrit-photon <photon-checkins@vmware.com>
Reviewed-by: Anish Swaminathan <anishs@vmware.com>

Alexey Makhalov authored on 2017/12/13 14:27:37
Showing 18 changed files
... ...
@@ -53,6 +53,11 @@ else
53 53
 PHOTON_RPMCHECK_OPTION :=
54 54
 endif
55 55
 
56
+# KAT build for FIPS certification
57
+ifdef KAT_BUILD
58
+PHOTON_KAT_BUILD_FLAGS := -F $(KAT_BUILD)
59
+endif
60
+
56 61
 TOOLS_BIN := $(SRCROOT)/tools/bin
57 62
 CONTAIN := $(TOOLS_BIN)/contain
58 63
 VIXDISKUTIL := $(TOOLS_BIN)/vixdiskutil
... ...
@@ -252,6 +257,7 @@ packages: check $(PHOTON_STAGE) $(PHOTON_PUBLISH_XRPMS) $(PHOTON_PUBLISH_RPMS) $
252 252
                 -v $(PHOTON_RELEASE_VERSION) \
253 253
                 -w $(PHOTON_STAGE)/pkg_info.json \
254 254
                 -g $(PHOTON_DATA_DIR)/pkg_build_options.json \
255
+		$(PHOTON_KAT_BUILD_FLAGS) \
255 256
                 $(PHOTON_RPMCHECK_OPTION) \
256 257
                 -t ${THREADS}
257 258
 
... ...
@@ -271,6 +277,7 @@ updated-packages: check $(PHOTON_STAGE) $(PHOTON_PUBLISH_XRPMS) $(PHOTON_PUBLISH
271 271
                 -n $(PHOTON_BUILD_NUMBER) \
272 272
                 -v $(PHOTON_RELEASE_VERSION) \
273 273
                 -k $(PHOTON_INPUT_RPMS_DIR) \
274
+		$(PHOTON_KAT_BUILD_FLAGS) \
274 275
                 $(PHOTON_RPMCHECK_OPTION) \
275 276
                 -t ${THREADS}
276 277
 
... ...
@@ -550,6 +557,7 @@ check-packer-ovf-plugin:
550 550
                               -n $(PHOTON_BUILD_NUMBER) \
551 551
                               -v $(PHOTON_RELEASE_VERSION) \
552 552
                               -g $(PHOTON_DATA_DIR)/pkg_build_options.json \
553
+			      $(PHOTON_KAT_BUILD_FLAGS) \
553 554
                               $(PHOTON_RPMCHECK_OPTION) \
554 555
                               -l $(PHOTON_LOGS_DIR)
555 556
 
556 557
new file mode 100644
... ...
@@ -0,0 +1,12 @@
0
+diff -Naur linux-4.9.66/crypto/testmgr.h linux-4.9.66-kat01/crypto/testmgr.h
1
+--- linux-4.9.66/crypto/testmgr.h	2017-12-08 07:39:22.824813034 +0000
2
+@@ -15591,7 +15591,7 @@
3
+ 			  "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17"
4
+ 			  "\xad\x2b\x41\x7b\xe6\x6c\x37\x10",
5
+ 		.ilen	= 64,
6
+-		.result	= "\x4f\x02\x1d\xb2\x43\xbc\x63\x3d"
7
++		.result	= "\x23\x32\x23\x32\x43\xbc\x63\x3d"
8
+ 			  "\x71\x78\x18\x3a\x9f\xa0\x71\xe8"
9
+ 			  "\xb4\xd9\xad\xa9\xad\x7d\xed\xf4"
10
+ 			  "\xe5\xe7\x38\x76\x3f\x69\x14\x5a"
0 11
new file mode 100644
... ...
@@ -0,0 +1,12 @@
0
+diff -Naur linux-4.9.66/crypto/testmgr.h linux-4.9.66-kat02/crypto/testmgr.h
1
+--- linux-4.9.66/crypto/testmgr.h	2017-12-08 07:39:22.824813034 +0000
2
+@@ -15475,7 +15475,7 @@
3
+ 			  "\x09\x79\xA0\x43\x5C\x0D\x08\x58"
4
+ 			  "\x17\xBB\xC0\x6B\x62\x3F\x56\xE9",
5
+ 		.ilen	= 496,
6
+-		.result	= "\x50\xB9\x22\xAE\x17\x80\x0C\x75"
7
++		.result	= "\x23\x32\x23\x32\x17\x80\x0C\x75"
8
+ 			  "\xDE\x47\xD3\x3C\xA5\x0E\x9A\x03"
9
+ 			  "\x6C\xF8\x61\xCA\x33\xBF\x28\x91"
10
+ 			  "\x1D\x86\xEF\x58\xE4\x4D\xB6\x1F"
0 11
new file mode 100644
... ...
@@ -0,0 +1,12 @@
0
+diff -Naur linux-4.9.66/crypto/testmgr.h linux-4.9.66-kat03/crypto/testmgr.h
1
+--- linux-4.9.66/crypto/testmgr.h	2017-12-08 07:39:22.824813034 +0000
2
+@@ -18490,7 +18490,7 @@
3
+ 			  "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7"
4
+ 			  "\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
5
+ 		.ilen	= 512,
6
+-		.result	= "\x1c\x3b\x3a\x10\x2f\x77\x03\x86"
7
++		.result	= "\x23\x32\x23\x32\x2f\x77\x03\x86"
8
+ 			  "\xe4\x83\x6c\x99\xe3\x70\xcf\x9b"
9
+ 			  "\xea\x00\x80\x3f\x5e\x48\x23\x57"
10
+ 			  "\xa4\xae\x12\xd4\x14\xa3\xe6\x3b"
0 11
new file mode 100644
... ...
@@ -0,0 +1,12 @@
0
+diff -Naur linux-4.9.66/crypto/testmgr.h linux-4.9.66-kat04/crypto/testmgr.h
1
+--- linux-4.9.66/crypto/testmgr.h	2017-12-08 07:39:22.824813034 +0000
2
+@@ -5711,7 +5711,7 @@
3
+ 			  "\x63\x65\x65\x72\x73\x74\x54\x20"
4
+ 			  "\x6f\x6f\x4d\x20\x6e\x61\x0a\x79",
5
+ 		.ilen	= 128,
6
+-		.result	= "\x0e\x2d\xb6\x97\x3c\x56\x33\xf4"
7
++		.result	= "\x23\x32\x23\x32\x3c\x56\x33\xf4"
8
+ 			  "\x67\x17\x21\xc7\x6e\x8a\xd5\x49"
9
+ 			  "\x74\xb3\x49\x05\xc5\x1c\xd0\xed"
10
+ 			  "\x12\x56\x5c\x53\x96\xb6\x00\x7d"
0 11
new file mode 100644
... ...
@@ -0,0 +1,12 @@
0
+diff -Naur linux-4.9.66/crypto/testmgr.h linux-4.9.66-kat05/crypto/testmgr.h
1
+--- linux-4.9.66/crypto/testmgr.h	2017-12-08 07:39:22.824813034 +0000
2
+@@ -5530,7 +5530,7 @@
3
+ 		.klen	= 24,
4
+ 		.input	= "\x18\xd7\x48\xe5\x63\x62\x05\x72",
5
+ 		.ilen	= 8,
6
+-		.result	= "\x73\x6f\x6d\x65\x64\x61\x74\x61",
7
++		.result	= "\x23\x32\x23\x32\x64\x61\x74\x61",
8
+ 		.rlen	= 8,
9
+ 	}, {
10
+ 		.key	= "\x03\x52\x02\x07\x67\x20\x82\x17"
0 11
new file mode 100644
... ...
@@ -0,0 +1,12 @@
0
+diff -Naur linux-4.9.66/crypto/testmgr.h linux-4.9.66-kat06/crypto/testmgr.h
1
+--- linux-4.9.66/crypto/testmgr.h	2017-12-08 07:39:22.824813034 +0000
2
+@@ -3060,7 +3060,7 @@
3
+ 		.ksize	= 20,
4
+ 		.plaintext = "Hi There",
5
+ 		.psize	= 8,
6
+-		.digest	= "\xb6\x17\x31\x86\x55\x05\x72\x64"
7
++		.digest	= "\x23\x32\x23\x32\x55\x05\x72\x64"
8
+ 			  "\xe2\x8b\xc0\xb6\xfb\x37\x8c\x8e\xf1"
9
+ 			  "\x46\xbe",
10
+ 	}, {
0 11
new file mode 100644
... ...
@@ -0,0 +1,12 @@
0
+diff -Naur linux-4.9.66/crypto/testmgr.h linux-4.9.66-kat07/crypto/testmgr.h
1
+--- linux-4.9.66/crypto/testmgr.h	2017-12-08 07:39:22.824813034 +0000
2
+@@ -3193,7 +3193,7 @@
3
+ 			"\x48\x61\x73\x68\x20\x4b\x65\x79"
4
+ 			"\x20\x46\x69\x72\x73\x74",
5
+ 		.psize  = 54,
6
+-		.digest = "\x95\xe9\xa0\xdb\x96\x20\x95\xad"
7
++		.digest = "\x23\x32\x23\x32\x96\x20\x95\xad"
8
+ 			"\xae\xbe\x9b\x2d\x6f\x0d\xbc\xe2"
9
+ 			"\xd4\x99\xf1\x12\xf2\xd2\xb7\x27"
10
+ 			"\x3f\xa6\x87\x0e",
0 11
new file mode 100644
... ...
@@ -0,0 +1,12 @@
0
+diff -Naur linux-4.9.66/crypto/testmgr.h linux-4.9.66-kat08/crypto/testmgr.h
1
+--- linux-4.9.66/crypto/testmgr.h	2017-12-08 07:39:22.824813034 +0000
2
+@@ -3261,7 +3261,7 @@
3
+ 		.ksize	= 32,
4
+ 		.plaintext = "abc",
5
+ 		.psize	= 3,
6
+-		.digest	= "\xa2\x1b\x1f\x5d\x4c\xf4\xf7\x3a"
7
++		.digest	= "\x23\x32\x23\x32\x4c\xf4\xf7\x3a"
8
+ 			  "\x4d\xd9\x39\x75\x0f\x7a\x06\x6a"
9
+ 			  "\x7f\x98\xcc\x13\x1c\xb1\x6a\x66"
10
+ 			  "\x92\x75\x90\x21\xcf\xab\x81\x81",
0 11
new file mode 100644
... ...
@@ -0,0 +1,12 @@
0
+diff -Naur linux-4.9.66/crypto/testmgr.h linux-4.9.66-kat09/crypto/testmgr.h
1
+--- linux-4.9.66/crypto/testmgr.h	2017-12-08 07:39:22.824813034 +0000
2
+@@ -3708,7 +3708,7 @@
3
+ 		.ksize	= 4,
4
+ 		.plaintext = "what do ya want for nothing?",
5
+ 		.psize	= 28,
6
+-		.digest	= "\xaf\x45\xd2\xe3\x76\x48\x40\x31"
7
++		.digest	= "\x23\x32\x23\x32\x76\x48\x40\x31"
8
+ 			  "\x61\x7f\x78\xd2\xb5\x8a\x6b\x1b"
9
+ 			  "\x9c\x7e\xf4\x64\xf5\xa0\x1b\x47"
10
+ 			  "\xe4\x2e\xc3\x73\x63\x22\x44\x5e"
0 11
new file mode 100644
... ...
@@ -0,0 +1,12 @@
0
+diff -Naur linux-4.9.66/crypto/testmgr.h linux-4.9.66-kat10/crypto/testmgr.h
1
+--- linux-4.9.66/crypto/testmgr.h	2017-12-08 07:39:22.824813034 +0000
2
+@@ -3797,7 +3797,7 @@
3
+ 		.ksize	= 20,
4
+ 		.plaintext = "Hi There",
5
+ 		.psize	= 8,
6
+-		.digest	= "\x87\xaa\x7c\xde\xa5\xef\x61\x9d"
7
++		.digest	= "\x23\x32\x23\x32\xa5\xef\x61\x9d"
8
+ 			  "\x4f\xf0\xb4\x24\x1a\x1d\x6c\xb0"
9
+ 			  "\x23\x79\xf4\xe2\xce\x4e\xc2\x78"
10
+ 			  "\x7a\xd0\xb3\x05\x45\xe1\x7c\xde"
... ...
@@ -2,7 +2,7 @@
2 2
 Summary:        Kernel
3 3
 Name:           linux
4 4
 Version:    	4.4.104
5
-Release:    	1%{?dist}
5
+Release:        2%{?kat_build:.%kat_build}%{?dist}
6 6
 License:    	GPLv2
7 7
 URL:        	http://www.kernel.org/
8 8
 Group:        	System Environment/Kernel
... ...
@@ -39,6 +39,9 @@ Patch18:        0002-allow-also-ecb-cipher_null.patch
39 39
 # Fix CVE-2017-11472
40 40
 Patch20:        ACPICA-Namespace-fix-operand-cache-leak.patch
41 41
 
42
+%if 0%{?kat_build:1}
43
+Patch1000:	%{kat_build}.patch
44
+%endif
42 45
 BuildRequires:  bc
43 46
 BuildRequires:  kbd
44 47
 BuildRequires:  kmod
... ...
@@ -129,6 +132,10 @@ This package contains the 'perf' performance analysis tools for Linux kernel.
129 129
 %patch18 -p1
130 130
 %patch20 -p1
131 131
 
132
+%if 0%{?kat_build:1}
133
+%patch1000 -p1
134
+%endif
135
+
132 136
 %build
133 137
 make mrproper
134 138
 cp %{SOURCE1} .config
... ...
@@ -280,6 +287,8 @@ ln -sf %{name}-%{uname_r}.cfg /boot/photon.cfg
280 280
 /usr/share/perf-core
281 281
 
282 282
 %changelog
283
+*   Tue Dec 12 2017 Alexey Makhalov <amakhalov@vmware.com> 4.4.104-2
284
+-   KAT build support
283 285
 *   Fri Dec 08 2017 Srivatsa S. Bhat <srivatsa@csail.mit.edu> 4.4.104-1
284 286
 -   Version update
285 287
 *   Mon Dec 04 2017 Srivatsa S. Bhat <srivatsa@csail.mit.edu> 4.4.103-1
... ...
@@ -102,25 +102,9 @@ class SerializableSpecObjectsUtils(object):
102 102
     def getRPMMacros(self):
103 103
         return self.userDefinedMacros
104 104
 
105
-    def processData(self, data):
106
-        for macroName in self.userDefinedMacros.keys():
107
-            value = self.userDefinedMacros[macroName]
108
-            macro="%{?"+macroName+"}"
109
-            if data.find(macro) != -1:
110
-                data = data.replace(macro,value)
111
-                continue
112
-            macro="%{"+macroName+"}"
113
-            if data.find(macro) != -1:
114
-                data = data.replace(macro,value)
115
-                continue
116
-            macro="%"+macroName
117
-            if data.find(macro) != -1:
118
-                data = data.replace(macro,value)
119
-        return data
120
-
121 105
     def getRelease(self, package):
122 106
         specName=self.getSpecName(package)
123
-        return self.processData(self.mapSerializableSpecObjects[specName].release)
107
+        return self.mapSerializableSpecObjects[specName].release
124 108
 
125 109
     def getVersion(self, package):
126 110
         specName=self.getSpecName(package)
... ...
@@ -192,24 +176,15 @@ class SerializableSpecObjectsUtils(object):
192 192
 
193 193
     def getURL(self, package):
194 194
         specName=self.getSpecName(package)
195
-        url = self.mapSerializableSpecObjects[specName].url
196
-        if url is None:
197
-            return None
198
-        return self.processData(url)
195
+        return self.mapSerializableSpecObjects[specName].url
199 196
 
200 197
     def getSourceURL(self, package):
201 198
         specName=self.getSpecName(package)
202
-        sourceurl = self.mapSerializableSpecObjects[specName].sourceurl
203
-        if sourceurl is None:
204
-            return None
205
-        return self.processData(sourceurl)
199
+        return self.mapSerializableSpecObjects[specName].sourceurl
206 200
 
207 201
     def getLicense(self, package):
208 202
         specName=self.getSpecName(package)
209
-        license = self.mapSerializableSpecObjects[specName].license
210
-        if license is None:
211
-            return None
212
-        return self.processData(license)
203
+        return self.mapSerializableSpecObjects[specName].license
213 204
 
214 205
     def printAllObjects(self):
215 206
         listSpecs=self.mapSerializableSpecObjects.keys()
... ...
@@ -1,4 +1,5 @@
1 1
 import re
2
+import constants
2 3
 from StringUtils import StringUtils
3 4
 from SpecStructures import *
4 5
 
... ...
@@ -13,7 +14,10 @@ class SpecParser(object):
13 13
         self.packages={}
14 14
         self.specAdditionalContent=""
15 15
         self.globalSecurityHardening=""
16
+        self.defs={}
16 17
         self.conditionalCheckMacroEnabled = False
18
+        self.macro_pattern = re.compile(r'%{(\S+?)\}')
19
+        self.userDefinedMacros = constants.constants.specData.getRPMMacros()
17 20
 
18 21
 
19 22
     def readPkgNameFromPackageMacro(self,data,basePkgName=None):
... ...
@@ -35,6 +39,71 @@ class SpecParser(object):
35 35
             return True, basePkgName
36 36
         return True, pkgName
37 37
 
38
+    def replaceMacros(self, string):
39
+        """Replace all macros in given string with corresponding values.
40
+
41
+        For example: a string '%{name}-%{version}.tar.gz' will be transformed to 'foo-2.0.tar.gz'.
42
+
43
+        :return A string where all macros in given input are substituted as good as possible.
44
+
45
+        """
46
+        def _is_conditional(macro):
47
+            return macro.startswith("?") or macro.startswith("!")
48
+
49
+        def _test_conditional(macro):
50
+            if macro[0] == "?":
51
+                return True
52
+            if macro[0] == "!":
53
+                return False
54
+            raise Exception("Given string is not a conditional macro")
55
+
56
+        def _is_macro_defined(macro):
57
+            return (macro in self.defs.keys()) or (macro in self.userDefinedMacros.keys())
58
+
59
+        def _get_macro(macro):
60
+            if macro in self.defs.keys():
61
+                return self.defs[macro]
62
+            elif macro in self.userDefinedMacros.keys():
63
+                return self.userDefinedMacros[macro]
64
+            raise Exception("Unknown macro: " + macro)
65
+
66
+        def _macro_repl(match):
67
+            macro_name = match.group(1)
68
+            if _is_conditional(macro_name):
69
+                parts = macro_name[1:].split(":")
70
+                assert len(parts) > 0
71
+                if _test_conditional(macro_name):  # ?
72
+                    if _is_macro_defined(parts[0]):
73
+                        if len(parts) == 2:
74
+                            return parts[1]
75
+                        else:
76
+                            return _get_macro(parts[0])
77
+                    else:
78
+                        return ""
79
+                else:  # !
80
+                    if not _is_macro_defined(parts[0]):
81
+                        if len(parts) == 2:
82
+                            return parts[1]
83
+                    return ""
84
+
85
+            if _is_macro_defined(macro_name):
86
+                return _get_macro(macro_name)
87
+            return match.string[match.start():match.end()]
88
+
89
+        #User macros
90
+        for macroName in self.userDefinedMacros.keys():
91
+            value = self.userDefinedMacros[macroName]
92
+            macro="%"+macroName
93
+            if string.find(macro) != -1:
94
+                string = string.replace(macro,value)
95
+        #Spec definitions
96
+        for macroName in self.defs.keys():
97
+            value = self.defs[macroName]
98
+            macro="%"+macroName
99
+            if string.find(macro) != -1:
100
+                string = string.replace(macro,value)
101
+        return re.sub(self.macro_pattern, _macro_repl, string)
102
+
38 103
     def parseSpecFile(self,specfile):
39 104
         self.createDefaultPackage()
40 105
         currentPkg="default"
... ...
@@ -44,13 +113,24 @@ class SpecParser(object):
44 44
         i=0
45 45
         while i < totalLines:
46 46
             line = lines[i].strip()
47
-            if self.isSpecMacro(line):
47
+            if self.isIfCondition(line):
48
+                if (not self.isConditionTrue(line)):
49
+                    # skip conditional body
50
+                    deep = 1
51
+                    while (i < totalLines and deep != 0):
52
+                        i=i+1
53
+                        line = lines[i].strip()
54
+                        if self.isConditionalMacroStart(line):
55
+                            deep = deep + 1
56
+                        elif self.isConditionalMacroEnd(line):
57
+                            deep = deep - 1
58
+            elif self.isSpecMacro(line):
48 59
                 macro,i=self.readMacroFromFile(i, lines)
49 60
                 self.updateMacro(macro)
50 61
             elif self.isPackageMacro(line):
51 62
                 defaultpkg = self.packages.get('default')
52 63
                 returnVal,packageName=self.readPkgNameFromPackageMacro(line, defaultpkg.name)
53
-                packageName=defaultpkg.decodeContents(packageName)
64
+                packageName=self.replaceMacros(packageName)
54 65
                 if not returnVal:
55 66
                     return False
56 67
                 if re.search('^'+'%package',line) :
... ...
@@ -74,7 +154,7 @@ class SpecParser(object):
74 74
                 self.readChecksum(line, self.packages[currentPkg])
75 75
             elif self.isConditionalCheckMacro(line):
76 76
                 self.conditionalCheckMacroEnabled = True
77
-            elif self.conditionalCheckMacroEnabled and self.isConditionalMacroCompleted(line):
77
+            elif self.conditionalCheckMacroEnabled and self.isConditionalMacroEnd(line):
78 78
                 self.conditionalCheckMacroEnabled = False
79 79
             else:
80 80
                 self.specAdditionalContent+=line+"\n"
... ...
@@ -133,7 +213,7 @@ class SpecParser(object):
133 133
         return False
134 134
 
135 135
     def isMacro(self,line):
136
-        return self.isPackageMacro(line) or self.isSpecMacro(line)
136
+        return self.isPackageMacro(line) or self.isSpecMacro(line) or self.isConditionalMacroStart(line) or self.isConditionalMacroEnd(line)
137 137
 
138 138
     def isSpecMacro(self,line):
139 139
         if re.search('^'+'%clean',line) :
... ...
@@ -265,12 +345,14 @@ class SpecParser(object):
265 265
         if not returnVal:
266 266
             return False
267 267
 
268
-        headerContent=pkg.decodeContents(headerContent)
268
+        headerContent=self.replaceMacros(headerContent)
269 269
         if headerName == 'summary':
270 270
             pkg.summary=headerContent
271 271
             return True
272 272
         if headerName == 'name':
273 273
             pkg.name=headerContent
274
+            if (pkg == self.packages["default"]):
275
+                self.defs["name"] = pkg.name
274 276
             return True
275 277
         if headerName == 'group':
276 278
             pkg.group=headerContent
... ...
@@ -280,12 +362,16 @@ class SpecParser(object):
280 280
             return True
281 281
         if headerName == 'version':
282 282
             pkg.version=headerContent
283
+            if (pkg == self.packages["default"]):
284
+                self.defs["version"] = pkg.version
283 285
             return True
284 286
         if headerName == 'buildarch':
285 287
             pkg.buildarch=headerContent
286 288
             return True
287 289
         if headerName == 'release':
288 290
             pkg.release=headerContent
291
+            if (pkg == self.packages["default"]):
292
+                self.defs["release"] = pkg.release
289 293
             return True
290 294
         if headerName == 'distribution':
291 295
             pkg.distribution=headerContent
... ...
@@ -337,7 +423,7 @@ class SpecParser(object):
337 337
 
338 338
     def readChecksum(self,line,pkg):
339 339
         strUtils = StringUtils()
340
-        line=pkg.decodeContents(line)
340
+        line=self.replaceMacros(line)
341 341
         data = line.strip();
342 342
         words=data.split()
343 343
         nrWords = len(words)
... ...
@@ -381,3 +467,24 @@ class SpecParser(object):
381 381
         if(words[0] != "%endif"):
382 382
             return False
383 383
         return True
384
+
385
+    def isIfCondition(self,line):
386
+        return line.startswith("%if ")
387
+
388
+    # Supports only %if %{}
389
+    def isConditionTrue(self,line):
390
+        data = line.strip()
391
+        words = data.split()
392
+        nrWords = len(words)
393
+        # condition like %if a > b is not supported
394
+        if(nrWords != 2):
395
+            return True
396
+        if (self.replaceMacros(words[1]) == "0"):
397
+            return False
398
+        return True
399
+
400
+    def isConditionalMacroStart(self,line):
401
+        return line.startswith("%if")
402
+
403
+    def isConditionalMacroEnd(self,line):
404
+        return (line.strip() == "%endif")
... ...
@@ -62,21 +62,6 @@ class Package(object):
62 62
             self.release=basePkg.release
63 63
             self.distribution=basePkg.distribution
64 64
 
65
-    def decodeContents(self,content):
66
-        if content.find("%{name}") != -1:
67
-            if self.basePkgName == "":
68
-                content = content.replace('%{name}',self.name)
69
-            else:
70
-                content = content.replace('%{name}',self.basePkgName)
71
-
72
-        if content.find("%{release}") != -1:
73
-            content = content.replace('%{release}',self.release)
74
-
75
-        if content.find("%{version}") != -1:
76
-            content = content.replace('%{version}',self.version)
77
-
78
-        return content
79
-
80 65
     def updatePackageMacro(self,macro):
81 66
         if macro.macroName == "%post":
82 67
             self.postMacro=macro
... ...
@@ -194,15 +194,6 @@ class Specutils(object):
194 194
                     dependentPackages.append(dpkg.package)
195 195
         return dependentPackages
196 196
 
197
-    def getCheckBuildRequires(self,pkgName):
198
-        dependentPackages=[]
199
-        for key in self.spec.packages.keys():
200
-            pkg = self.spec.packages.get(key)
201
-            if pkg.name == pkgName:
202
-                for dpkg in pkg.checkbuildrequires:
203
-                    dependentPackages.append(dpkg.package)
204
-        return dependentPackages
205
-
206 197
     def getProvides(self,packageName):
207 198
         dependentPackages=[]
208 199
         defaultPkgName=self.spec.packages['default'].name
... ...
@@ -40,6 +40,7 @@ def main():
40 40
     parser.add_option("-y",  "--generate-pkg-yaml-files",  dest="generatePkgYamlFiles",  default=False, action ="store_true")
41 41
     parser.add_option("-j",  "--pkg-yaml-dir-path",  dest="pkgYamlDirPath",  default="../../stage/")
42 42
     parser.add_option("-f",  "--pkg-blacklist-file",  dest="pkgBlacklistFile",  default=None)
43
+    parser.add_option("-F",  "--kat-build", dest="katBuild",  default=None)
43 44
 
44 45
     (options,  args) = parser.parse_args()
45 46
     cmdUtils=CommandUtils()
... ...
@@ -1,4 +1,5 @@
1 1
 from SpecData import SerializableSpecObjectsUtils
2
+from SpecUtils import Specutils
2 3
 
3 4
 class constants(object):
4 5
     specPath=""
... ...
@@ -312,16 +313,20 @@ class constants(object):
312 312
         constants.logPath = options.logPath
313 313
         constants.prevPublishRPMRepo=options.publishRPMSPath
314 314
         constants.prevPublishXRPMRepo = options.publishXRPMSPath
315
-	constants.buildRootPath=options.buildRootPath
316
-        constants.specData = SerializableSpecObjectsUtils(constants.logPath)
317
-        constants.specData.readSpecsAndConvertToSerializableObjects(constants.specPath)
315
+        constants.buildRootPath=options.buildRootPath
318 316
         constants.pullsourcesConfig = options.pullsourcesConfig
319 317
         constants.inputRPMSPath=options.inputRPMSPath
320 318
         constants.rpmCheck = options.rpmCheck
321
-        constants.updateRPMMacros()
319
+        constants.specData = SerializableSpecObjectsUtils(constants.logPath)
320
+        constants.updateRPMMacros(options)
321
+        # Perform full parsing now
322
+        constants.specData.readSpecsAndConvertToSerializableObjects(constants.specPath)
322 323
         
323 324
     @staticmethod
324
-    def updateRPMMacros():
325
+    def updateRPMMacros(options):
326
+        if options.katBuild != None:
327
+            constants.specData.addMacro("kat_build", options.katBuild)
328
+
325 329
         #adding distribution rpm macro
326 330
         constants.specData.addMacro("dist",constants.dist)
327 331
 
... ...
@@ -331,27 +336,30 @@ class constants(object):
331 331
         #adding releasenumber rpm macro
332 332
         constants.specData.addMacro("photon_release_version",constants.releaseVersion)
333 333
 
334
+        #adding check rpm macro
335
+        constants.specData.addMacro("with_check","0")
336
+
337
+	    #adding openjre version rpm macro
338
+        spec = Specutils(constants.specPath + "/openjdk/openjdk.spec")
339
+        javaversion = spec.getVersion()
340
+        constants.specData.addMacro("JAVA_VERSION",javaversion)
341
+
342
+
334 343
         #adding kernelversion rpm macro
335
-        kernelversion = constants.specData.getVersion("linux")
344
+        spec = Specutils(constants.specPath + "/linux/linux.spec")
345
+        kernelversion = spec.getVersion()
336 346
         constants.specData.addMacro("KERNEL_VERSION",kernelversion)
337 347
 
338 348
         #adding kernelrelease rpm macro
339
-        kernelrelease = constants.specData.getRelease("linux")
349
+        kernelrelease = spec.getRelease()
340 350
         constants.specData.addMacro("KERNEL_RELEASE",kernelrelease)
341 351
        
342
-	#adding openjre version rpm macro
343
-        javaversion = constants.specData.getVersion("openjre")
344
-        constants.specData.addMacro("JAVA_VERSION",javaversion)
345
-
346 352
         #adding kernelsubrelease rpm macro
347 353
         kernelversion = kernelversion.replace(".","")
348 354
         if kernelversion.isdigit():
349 355
             kernelversion = int(kernelversion) << 8
350
-        kernelsubrelease = str(kernelversion)+kernelrelease
351
-        kernelsubrelease = kernelsubrelease.replace(constants.dist,"")
356
+        kernelsubrelease = str(kernelversion)+kernelrelease.split('.')[0]
352 357
         if kernelsubrelease:
353 358
             kernelsubrelease = "."+kernelsubrelease
354 359
             constants.specData.addMacro("kernelsubrelease",kernelsubrelease) 
355 360
 
356
-        #adding check rpm macro
357
-        constants.specData.addMacro("with_check","0")