Browse code

Adding logic to build source iso with package info text file

Change-Id: Id21c030ed8ee6fe677115679f12e5aedaca4912f
Reviewed-on: http://photon-jenkins.eng.vmware.com/560
Tested-by: jenkins-photon <wangnan2015@hotmail.com>
Reviewed-by: suezzelur <anishs@vmware.com>

dthaluru authored on 2016/02/24 02:27:16
Showing 7 changed files
... ...
@@ -56,7 +56,7 @@ clean-install clean-chroot build-updated-packages
56 56
 
57 57
 THREADS?=1
58 58
 
59
-all: iso minimal-iso docker-image ostree-host-iso live-iso cloud-image-all
59
+all: iso minimal-iso docker-image ostree-host-iso live-iso cloud-image-all src-iso
60 60
 
61 61
 micro: micro-iso
62 62
 	@:
... ...
@@ -164,12 +164,30 @@ iso: check $(PHOTON_STAGE) $(PHOTON_PACKAGES) ostree-repo
164 164
                 -w $(PHOTON_STAGE)/photon_iso \
165 165
                 -l $(PHOTON_STAGE)/LOGS \
166 166
                 -r $(PHOTON_STAGE)/RPMS \
167
+                -x $(PHOTON_STAGE)/SRPMS \
167 168
                 -p $(PHOTON_GENERATED_DATA_DIR)/$(FULL_PACKAGE_LIST_FILE) \
168 169
                 -o $(PHOTON_STAGE)/common/data \
169 170
                 -s $(PHOTON_DATA_DIR) \
170 171
                 -f > \
171 172
                 $(PHOTON_LOGS_DIR)/installer.log 2>&1
172 173
 
174
+src-iso: check $(PHOTON_STAGE) $(PHOTON_PACKAGES)
175
+	@echo "Building Photon Full Source ISO..."
176
+	@cd $(PHOTON_INSTALLER_DIR) && \
177
+        sudo $(PHOTON_INSTALLER) \
178
+                -j $(PHOTON_STAGE)/photon-$(PHOTON_RELEASE_VERSION)-$(PHOTON_BUILD_NUMBER).src.iso \
179
+                -w $(PHOTON_STAGE)/photon_iso \
180
+                -l $(PHOTON_STAGE)/LOGS \
181
+                -r $(PHOTON_STAGE)/RPMS \
182
+                -x $(PHOTON_STAGE)/SRPMS \
183
+                -p $(PHOTON_GENERATED_DATA_DIR)/$(FULL_PACKAGE_LIST_FILE) \
184
+                -o $(PHOTON_STAGE)/common/data \
185
+                -s $(PHOTON_DATA_DIR) \
186
+                -u $(PHOTON_DATA_DIR)/pkg_info.json\
187
+                -z $(PHOTON_STAGE)/pkg_info.txt\
188
+                -f > \
189
+                $(PHOTON_LOGS_DIR)/sourceiso-installer.log 2>&1
190
+
173 191
 pkgtree:
174 192
 	@cd $(PHOTON_SPECDEPS_DIR) && \
175 193
 		$(PHOTON_SPECDEPS) -s $(PHOTON_SPECS_DIR) -i pkg -p $(pkg)
... ...
@@ -198,6 +216,7 @@ packages: check $(PHOTON_STAGE) $(PHOTON_PUBLISH_RPMS) $(PHOTON_SOURCES) $(CONTA
198 198
                 -d $(PHOTON_DIST_TAG) \
199 199
                 -n $(PHOTON_BUILD_NUMBER) \
200 200
                 -v $(PHOTON_RELEASE_VERSION) \
201
+                -w $(PHOTON_DATA_DIR)/pkg_info.json\
201 202
                 $(PHOTON_RPMCHECK_OPTION) \
202 203
                 -t ${THREADS}
203 204
 
204 205
new file mode 100755
... ...
@@ -0,0 +1,45 @@
0
+#!/bin/bash
1
+#################################################
2
+#       Title:  mk-src-iso                      #
3
+#        Date:  2016-02-19                      #
4
+#     Version:  1.0                             #
5
+#      Author:  dthaluru@vmware.com             #
6
+#     Options:                                  #
7
+#################################################
8
+#	Overview
9
+#		Generates a photon source iso
10
+#	End
11
+#
12
+
13
+set +x                 # disable hashall
14
+PRGNAME=${0##*/}	    # script name minus the path
15
+source config.inc		#	configuration parameters
16
+source function.inc		#	commonn functions
17
+LOGFILE=/var/log/"${PRGNAME}-${LOGFILE}"	#	set log file name
18
+
19
+
20
+# Grab the name of the iso file 
21
+if [ $# -lt 2 ]
22
+then
23
+    echo "Usage : " $0 " <output-iso-with-path>  <srpms-path> <pkg-list-path>"
24
+    exit 1
25
+fi
26
+ISO_OUTPUT_NAME=$1
27
+SRPMS_PATH=$2
28
+SRPM_LIST=$3
29
+
30
+WORKINGDIR=${BUILDROOT}
31
+rm -r ${WORKINGDIR}/*
32
+(
33
+cd ${SRPMS_PATH}
34
+mkdir ${WORKINGDIR}/SRPMS
35
+for srpm_name in $SRPM_LIST; do
36
+    FILENAME="`find . -name "$srpm_name-[0-9]*" -type f`"
37
+    if [ -n "$FILENAME" ]; then
38
+        cp --parent $FILENAME ${WORKINGDIR}/SRPMS/;
39
+    fi
40
+done
41
+)
42
+
43
+mkisofs -r -o $ISO_OUTPUT_NAME $WORKINGDIR/
44
+
... ...
@@ -14,6 +14,7 @@ import sys
14 14
 import os
15 15
 from jsonwrapper import JsonWrapper
16 16
 from packageselector import PackageSelector
17
+import json
17 18
 
18 19
 def query_yes_no(question, default="no"):
19 20
     valid = {"yes": True, "y": True, "ye": True,
... ...
@@ -120,23 +121,43 @@ def get_live_cd_status_string(build_install_option):
120 120
                 return "true"
121 121
     return "false"
122 122
 
123
+def generate_pkginfo_text_file(list_rpms, pkg_info_json_file_path, pkg_info_text_file_path):
124
+    if not os.path.isfile(pkg_info_json_file_path):
125
+        return
126
+    pkg_info_json_file = open(pkg_info_json_file_path,'r')
127
+    data = json.load(pkg_info_json_file)
128
+    pkg_info_json_file.close()
129
+    list_lines = []
130
+    list_lines.append("#%{name},%{version},%{release},%{arch},%{sourcerpm}\n") 
131
+    for rpm in list_rpms:
132
+       if data.has_key(rpm):
133
+           list_lines.append(data[rpm]["name"]+","+data[rpm]["version"]+","+data[rpm]["release"]+","+data[rpm]["arch"]+","+data[rpm]["sourcerpm"]+"\n") 
134
+    pkg_info_text_file = open(pkg_info_text_file_path,'w')
135
+    pkg_info_text_file.writelines(list_lines)
136
+    pkg_info_text_file.close()
137
+
123 138
 if __name__ == '__main__':
124 139
     usage = "Usage: %prog [options] <config file> <tools path>"
125 140
     parser = OptionParser(usage)
126 141
 
127 142
     parser.add_option("-i", "--iso-path",  dest="iso_path")
143
+    parser.add_option("-j", "--src-iso-path",  dest="src_iso_path")
128 144
     parser.add_option("-v", "--vmdk-path", dest="vmdk_path")
129 145
     parser.add_option("-w",  "--working-directory",  dest="working_directory", default="/mnt/photon-root")
130 146
     parser.add_option("-l",  "--log-path",  dest="log_path", default="../stage/LOGS")
131 147
     parser.add_option("-r",  "--rpm-path",  dest="rpm_path", default="../stage/RPMS")
148
+    parser.add_option("-x",  "--srpm-path",  dest="srpm_path", default="../stage/SRPMS")
132 149
     parser.add_option("-o", "--output-data-path", dest="output_data_path", default="../stage/common/data/")
133 150
     parser.add_option("-f", "--force", action="store_true", dest="force", default=False)
134 151
     parser.add_option("-p", "--package-list-file", dest="package_list_file", default="../common/data/build_install_options_all.json")
135 152
     parser.add_option("-m", "--stage-path", dest="stage_path", default="../stage")
136 153
     parser.add_option("-c", "--dracut-configuration", dest="dracut_configuration_file", default="../common/data/dracut_configuration.json")
137 154
     parser.add_option("-s", "--json-data-path", dest="json_data_path", default="../stage/common/data/")
155
+    parser.add_option("-u", "--pkginfo-json-file", dest="pkginfo_json_file", default="../common/data/pkg_info.json")
156
+    parser.add_option("-z", "--pkginfo-txt-file", dest="pkginfo_txt_file", default="../stage/pkg_info.txt")
157
+
138 158
     (options,  args) = parser.parse_args()
139
-    if options.iso_path:
159
+    if options.iso_path or options.src_iso_path:
140 160
         # Check the arguments
141 161
         if (len(args)) != 0:
142 162
             parser.error("Incorrect arguments")
... ...
@@ -198,7 +219,7 @@ if __name__ == '__main__':
198 198
 
199 199
     config['packages'] = packages
200 200
 
201
-    if config['iso_system'] == True:
201
+    if options.iso_path:
202 202
         if os.path.isfile(options.dracut_configuration_file):
203 203
             json_wrapper_package_list = JsonWrapper(options.dracut_configuration_file)
204 204
             dracut_configuration_list_json = json_wrapper_package_list.read()
... ...
@@ -227,19 +248,27 @@ if __name__ == '__main__':
227 227
     package_installer.install(None)
228 228
 
229 229
     # Making the iso if needed
230
-    if config['iso_system']:
230
+    if options.iso_path:
231 231
         rpm_list = " ".join(create_rpm_list_to_copy_in_iso(options.package_list_file, options.output_data_path))
232 232
         files_to_copy = " ".join(create_additional_file_list_to_copy_in_iso(os.path.abspath(options.stage_path), options.package_list_file))
233 233
         live_cd = get_live_cd_status_string(options.package_list_file)
234 234
         process = subprocess.Popen(['./mk-install-iso.sh', '-w', options.working_directory, options.iso_path, options.rpm_path, options.package_list_file, rpm_list, options.stage_path, files_to_copy, live_cd, options.json_data_path])
235 235
         retval = process.wait()
236 236
 
237
+    if options.src_iso_path:
238
+        rpm_list = " ".join(create_rpm_list_to_copy_in_iso(options.package_list_file, options.output_data_path))
239
+        process = subprocess.Popen(['./mk-src-iso.sh', '-w', options.working_directory, options.src_iso_path, options.srpm_path, rpm_list])
240
+        retval = process.wait()
241
+        list_rpms = rpm_list.split(" ")
242
+        list_rpms = list(set(list_rpms))
243
+        generate_pkginfo_text_file(list_rpms, options.pkginfo_json_file, options.pkginfo_txt_file)
244
+
237 245
     # Cleaning up for vmdk
238 246
     if 'vmdk_install' in config and config['vmdk_install']:
239 247
         process = subprocess.Popen(['./mk-clean-vmdk.sh', config['disk']['disk']])
240 248
         process.wait()
241 249
 
242 250
     #Clean up the working directories
243
-    if (options.iso_path or options.vmdk_path):
251
+    if (options.iso_path or options.vmdk_path or options.src_iso_path):
244 252
         process = subprocess.Popen(['rm', '-rf', options.working_directory])
245 253
         retval = process.wait()
246 254
new file mode 100644
... ...
@@ -0,0 +1,44 @@
0
+import json
1
+from Logger import Logger
2
+from constants import constants
3
+import os.path
4
+from CommandUtils import CommandUtils
5
+
6
+class SourcePackageInfo(object):
7
+     sourcePkgList = {}
8
+     logger = None
9
+
10
+
11
+     @staticmethod
12
+     def setLogging(logName=None,logPath=None):
13
+        if logName is None:
14
+            logName = "SourcePackageInfo"
15
+        if logPath is None:
16
+            logPath = constants.logPath
17
+        SourcePackageInfo.logger=Logger.getLogger(logName,logPath)
18
+
19
+     @staticmethod
20
+     def loadPkgInfoFromFile(filePath):
21
+         SourcePackageInfo.logger.info("Loading source package list from the json file")
22
+         if not os.path.isfile(filePath):
23
+             return
24
+         pkgInfoFile = open(filePath,'r')
25
+         SourcePackageInfo.sourcePkgList = json.load(pkgInfoFile)
26
+         pkgInfoFile.close()
27
+
28
+     @staticmethod
29
+     def addSRPMData(packageName,version,release,arch,srpmFile):
30
+         listPkgAttributes={"name":packageName,"version":version,"release":release,"arch":arch,"sourcerpm":srpmFile}
31
+         SourcePackageInfo.sourcePkgList[packageName]=listPkgAttributes
32
+         SourcePackageInfo.logger.info("Added source package to the list:"+packageName)
33
+
34
+     @staticmethod
35
+     def writePkgListToFile(fileName):
36
+         SourcePackageInfo.logger.info("Writing source package list to the json file")
37
+         cmdUtils=CommandUtils()
38
+         dirPath=os.path.basename(fileName)
39
+         if not os.path.isdir(dirPath):
40
+             cmdUtils.runCommandInShell("mkdir -p "+dirPath)
41
+         pkgInfoFile = open(fileName,'w+')
42
+         json.dump(SourcePackageInfo.sourcePkgList, pkgInfoFile,indent=4)
43
+         pkgInfoFile.close()
... ...
@@ -6,6 +6,7 @@ from constants import constants
6 6
 import re
7 7
 from time import sleep
8 8
 import PullSources
9
+from PackageInfo import SourcePackageInfo
9 10
 
10 11
 class PackageUtils(object):
11 12
     
... ...
@@ -36,12 +37,16 @@ class PackageUtils(object):
36 36
         self.noDepsRPMFilesToInstallInAOneShot=""
37 37
         self.noDepsPackagesToInstallInAOneShot=""
38 38
     
39
-    def getRPMDestDir(self,rpmName,rpmDir):
39
+    def getRPMArch(self,rpmName):
40 40
         arch=""
41 41
         if rpmName.find("x86_64") != -1:
42
-            arch='x86_64'
42
+            arch="x86_64"
43 43
         elif rpmName.find("noarch") != -1:
44 44
             arch="noarch"
45
+        return arch
46
+
47
+    def getRPMDestDir(self,rpmName,rpmDir):
48
+        arch = self.getRPMArch(rpmName)
45 49
         rpmDestDir=rpmDir+"/"+arch
46 50
         return rpmDestDir
47 51
     
... ...
@@ -158,13 +163,19 @@ class PackageUtils(object):
158 158
         finally:
159 159
             if destLogPath is not None:
160 160
                 shutil.copy2(chrootLogsFilePath, destLogPath)
161
-
161
+        self.logger.info("RPM build is successful")
162
+        arch = self.getRPMArch(listRPMFiles[0])
163
+       
162 164
         for rpmFile in listRPMFiles:
163 165
             self.copyRPM(chrootID+"/"+rpmFile, constants.rpmPath)
164
-
166
+        
165 167
         for srpmFile in listSRPMFiles:
166 168
             self.copyRPM(chrootID+"/"+srpmFile, constants.sourceRpmPath)
169
+            srpmName = os.path.basename(srpmFile)
170
+            package,version,release = self.findPackageInfoFromSourceRPMFile(srpmFile)
171
+            SourcePackageInfo.addSRPMData(package,version,release,arch,srpmName)
167 172
 
173
+    
168 174
     def buildRPM(self,specFile,logFile,chrootCmd):
169 175
         
170 176
         rpmBuildcmd= self.rpmbuildBinary+" "+self.rpmbuildBuildallOption+" "+self.rpmbuildDistOption
... ...
@@ -242,7 +253,23 @@ class PackageUtils(object):
242 242
         version=rpmfile[versionindex+1:releaseindex]
243 243
         release=rpmfile[releaseindex+1:]
244 244
         return packageName,version,release
245
-    
245
+
246
+    def findPackageInfoFromSourceRPMFile(self,sourcerpmfile):
247
+        sourcerpmfile=os.path.basename(sourcerpmfile)
248
+        sourcerpmfile=sourcerpmfile.replace(".src.rpm","")
249
+        releaseindex=sourcerpmfile.rfind("-")
250
+        if releaseindex == -1:
251
+            self.logger.error("Invalid source rpm file:"+sourcerpmfile)
252
+            raise Exception("Invalid Source RPM")
253
+        versionindex=sourcerpmfile[0:releaseindex].rfind("-")
254
+        if versionindex == -1:
255
+            self.logger.error("Invalid source rpm file:"+sourcerpmfile)
256
+            raise Exception("Invalid source RPM")
257
+        packageName=sourcerpmfile[0:versionindex]
258
+        version=sourcerpmfile[versionindex+1:releaseindex]
259
+        release=sourcerpmfile[releaseindex+1:]
260
+        return packageName,version,release
261
+ 
246 262
     def findInstalledRPMPackages(self, chrootID):
247 263
         cmd = self.rpmBinary+" "+self.queryRpmPackageOptions
248 264
         chrootCmd=self.runInChrootCommand+" "+chrootID
... ...
@@ -49,9 +49,12 @@ class ToolChainUtils(object):
49 49
             cmd=self.rpmbuildCommand+" -ba --nocheck --define \'_topdir "+chrootID+constants.topDirPath+"\' --define \'_dbpath "+chrootID+"/var/lib/rpm\' --define \'dist "+constants.dist+"\' --define \'photon_build_number "+constants.buildNumber+"\' --define \'photon_release_version "+constants.releaseVersion+"\' "+specFile
50 50
             self.logger.info(cmd)
51 51
             cmdUtils.runCommandInShell(cmd,self.logPath+"/filesystem.log")
52
-            filesystemrpmFile = cmdUtils.findFile(package+"-*.rpm", chrootID+constants.topDirPath+"/RPMS")
52
+            filesystemrpmFile = cmdUtils.findFile(package+"-[0-9]*.rpm", chrootID+constants.topDirPath+"/RPMS")
53
+            filesystemsrpmFile = cmdUtils.findFile(package+"-[0-9]*.src.rpm", chrootID+constants.topDirPath+"/SRPMS")
53 54
             if len(filesystemrpmFile) > 0:
54 55
                 shutil.copy2(filesystemrpmFile[0],constants.rpmPath+"/x86_64/")
56
+            if len(filesystemsrpmFile) > 0:
57
+                shutil.copy2(filesystemsrpmFile[0],constants.sourceRpmPath+"/")
55 58
             rpmFile=pkgUtils.findRPMFileForGivenPackage(package)
56 59
             if rpmFile is None:
57 60
                 self.logger.error("Cannot find filesystem rpm")
... ...
@@ -12,6 +12,7 @@ from SpecUtils import Specutils
12 12
 from StringUtils import StringUtils
13 13
 import collections
14 14
 import traceback
15
+from PackageInfo import SourcePackageInfo
15 16
 
16 17
 def main():
17 18
     usage = "Usage: %prog [options] <package name>"
... ...
@@ -35,16 +36,18 @@ def main():
35 35
     parser.add_option("-v",  "--release-version", dest="releaseVersion",  default="NNNnNNN")
36 36
     parser.add_option("-u",  "--enable-rpmcheck", dest="rpmCheck",  default=False, action ="store_true")
37 37
     parser.add_option("-a",  "--source-rpm-path",  dest="sourceRpmPath",  default="../../stage/SRPMS")
38
+    parser.add_option("-w",  "--pkginfo-file",  dest="pkgInfoFile",  default="../../common/data/pkg_info.json")
38 39
 
39 40
     (options,  args) = parser.parse_args()
40 41
     cmdUtils=CommandUtils()
41 42
     if not os.path.isdir(options.logPath):
42 43
         cmdUtils.runCommandInShell("mkdir -p "+options.logPath)
43
-    
44
+
44 45
     logger=Logger.getLogger(options.logPath+"/Main")
45 46
     
46 47
     errorFlag=False
47 48
     package = None
49
+    pkgInfoJsonFile=options.pkgInfoFile
48 50
     if not os.path.isdir(options.sourcePath):
49 51
         logger.error("Given Sources Path is not a directory:"+options.sourcePath)
50 52
         errorFlag = True
... ...
@@ -102,25 +105,10 @@ def main():
102 102
     else:
103 103
         logger.info("Package to build:"+package)
104 104
 
105
-    '''    
106
-    listPackages=["acl","attr","autoconf","automake","bash","bc","bindutils","binutils","bison","boost","btrfs-progs","bzip2","ca-certificates","cdrkit","check",
107
-                  "cloud-init","cmake","coreutils","cpio","cracklib","createrepo","curl","cyrus-sasl","db","dbus","deltarpm","diffutils","docbook-xml","docbook-xsl",
108
-                  "docker","dracut","e2fsprogs","elfutils","etcd","expat","file","filesystem","findutils","flex","gawk","gcc","gdb","gdbm","gettext","git",
109
-                  "glib","glibc","glibmm","gmp","go","gobject-introspection","google-daemon","google-startup-scripts","gperf","gpgme","gptfdisk","grep","groff",
110
-                  "grub","gtk-doc","gzip","haveged","hawkey","iana-etc","inetutils","intltool","iproute2","iptables","itstool","json-glib","kbd","kmod","krb5",
111
-                  "kubernetes","less","libaio","libassuan","libcap","libdnet","libffi","libgpg-error","libgsystem","libhif","libmspack","libpcap","libpipeline",
112
-                  "librepo","libselinux","libsepol","libsigc++","libsolv","libtool","libxml2","libxslt","libyaml","linux","linux-api-headers","Linux-PAM","lua",
113
-                  "lvm2","lzo","m4","make","man-db","man-pages","mercurial","mpc","mpfr","nano","ncurses","nspr","nss","ntp","openldap","openssh","openssl",
114
-                  "open-vm-tools","ostree","parted","patch","pcre","perl","perl-common-sense","perl-Config-IniFiles","perl-DBD-SQLite","perl-DBI","perl-DBIx-Simple",
115
-                  "perl-Exporter-Tiny","perl-JSON-XS","perl-libintl","perl-List-MoreUtils","perl-Module-Install","perl-Module-ScanDeps","perl-Types-Serialiser",
116
-                  "perl-WWW-Curl","perl-YAML","perl-YAML-Tiny","photon-release","pkg-config","popt","procps-ng","psmisc","pycurl","pygobject","python2",
117
-                  "python-configobj","python-iniparse","python-jsonpatch","python-jsonpointer","python-prettytable","python-requests","python-setuptools",
118
-                  "python-six","PyYAML","readline","rocket","rpm","rpm-ostree","rpm-ostree-toolbox","ruby","sed","shadow","sqlite-autoconf","strace","sudo",
119
-                  "swig","systemd","tar","tcpdump","tcsh","tdnf","texinfo","thin-provisioning-tools","tzdata","unzip","urlgrabber","util-linux","vim","wget",
120
-                  "which","xerces-c","XML-Parser","xml-security-c","xz","yum","yum-metadata-parser","zlib"]
121
-    '''
122 105
     try:
123 106
         constants.initialize(options)
107
+        SourcePackageInfo.setLogging()
108
+        SourcePackageInfo.loadPkgInfoFromFile(pkgInfoJsonFile)
124 109
         if package == "packages_list":
125 110
             buildPackagesList(options.specPath, options.buildRootPath+"/../packages_list.csv")
126 111
         elif package == "sources_list":
... ...
@@ -141,7 +129,9 @@ def main():
141 141
         # print stacktrace
142 142
         traceback.print_exc()
143 143
         sys.exit(1)
144
-    
144
+
145
+    logger.info("Writing Package info to the file:"+pkgInfoJsonFile)
146
+    SourcePackageInfo.writePkgListToFile(pkgInfoJsonFile)   
145 147
     sys.exit(0)
146 148
 
147 149
 def buildToolChain(buildThreads):