1## @file 2# Install distribution package. 3# 4# Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR> 5# 6# This program and the accompanying materials are licensed and made available 7# under the terms and conditions of the BSD License which accompanies this 8# distribution. The full text of the license may be found at 9# http://opensource.org/licenses/bsd-license.php 10# 11# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 12# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 13# 14 15''' 16MkPkg 17''' 18 19## 20# Import Modules 21# 22from os import remove 23from os import getcwd 24from os import chdir 25import os.path 26from sys import stdin 27from sys import platform 28from traceback import format_exc 29from platform import python_version 30import md5 31from time import strftime 32from time import localtime 33from uuid import uuid4 34 35from Logger import StringTable as ST 36from Logger.ToolError import OPTION_UNKNOWN_ERROR 37from Logger.ToolError import OPTION_VALUE_INVALID 38from Logger.ToolError import ABORT_ERROR 39from Logger.ToolError import UPT_REPKG_ERROR 40from Logger.ToolError import CODE_ERROR 41from Logger.ToolError import FatalError 42from Logger.ToolError import FILE_NOT_FOUND 43import Logger.Log as Logger 44 45from Xml.XmlParser import DistributionPackageXml 46from Xml.IniToXml import IniToXml 47 48from Library import GlobalData 49from Library.ParserValidate import IsValidPath 50 51from Core.DistributionPackageClass import DistributionPackageClass 52from Core.PackageFile import PackageFile 53from Common.MultipleWorkspace import MultipleWorkspace as mws 54 55## CheckForExistingDp 56# 57# Check if there is a same name DP file existing 58# @param Path: The path to be checked 59# 60def CheckForExistingDp(Path): 61 if os.path.exists(Path): 62 Logger.Info(ST.MSG_DISTRIBUTION_PACKAGE_FILE_EXISTS % Path) 63 Input = stdin.readline() 64 Input = Input.replace('\r', '').replace('\n', '') 65 if Input.upper() != "Y": 66 Logger.Error("\nMkPkg", ABORT_ERROR, ST.ERR_USER_ABORT, RaiseError=True) 67 68## Tool entrance method 69# 70# This method mainly dispatch specific methods per the command line options. 71# If no error found, return zero value so the caller of this tool can know 72# if it's executed successfully or not. 73# 74# 75def Main(Options = None): 76 if Options == None: 77 Logger.Error("\nMkPkg", OPTION_UNKNOWN_ERROR, ST.ERR_OPTION_NOT_FOUND) 78 try: 79 DataBase = GlobalData.gDB 80 ContentFileClosed = True 81 WorkspaceDir = GlobalData.gWORKSPACE 82 83 # 84 # Init PackFileToCreate 85 # 86 if not Options.PackFileToCreate: 87 Logger.Error("\nMkPkg", OPTION_UNKNOWN_ERROR, ST.ERR_OPTION_NOT_FOUND) 88 89 # 90 # Handle if the distribution package file already exists 91 # 92 CheckForExistingDp(Options.PackFileToCreate) 93 94 # 95 # Check package file existing and valid 96 # 97 CheckFileList('.DEC', Options.PackageFileList, ST.ERR_INVALID_PACKAGE_NAME, ST.ERR_INVALID_PACKAGE_PATH) 98 # 99 # Check module file existing and valid 100 # 101 CheckFileList('.INF', Options.ModuleFileList, ST.ERR_INVALID_MODULE_NAME, ST.ERR_INVALID_MODULE_PATH) 102 103 # 104 # Get list of files that installed with RePackage attribute available 105 # 106 RePkgDict = DataBase.GetRePkgDict() 107 108 ContentFile = PackageFile(GlobalData.gCONTENT_FILE, "w") 109 ContentFileClosed = False 110 111 # 112 # Add temp distribution header 113 # 114 if Options.PackageInformationDataFile: 115 XmlFile = IniToXml(Options.PackageInformationDataFile) 116 DistPkg = DistributionPackageXml().FromXml(XmlFile) 117 remove(XmlFile) 118 119 # 120 # add distribution level tool/misc files 121 # before pack, current dir should be workspace dir, else the full 122 # path will be in the pack file 123 # 124 Cwd = getcwd() 125 chdir(WorkspaceDir) 126 ToolObject = DistPkg.Tools 127 MiscObject = DistPkg.MiscellaneousFiles 128 FileList = [] 129 if ToolObject: 130 FileList += ToolObject.GetFileList() 131 if MiscObject: 132 FileList += MiscObject.GetFileList() 133 for FileObject in FileList: 134 # 135 # If you have unicode file names, please convert them to byte 136 # strings in your desired encoding before passing them to 137 # write(). 138 # 139 FromFile = os.path.normpath(FileObject.GetURI()).encode('utf_8') 140 FileFullPath = mws.join(WorkspaceDir, FromFile) 141 if FileFullPath in RePkgDict: 142 (DpGuid, DpVersion, DpName, Repackage) = RePkgDict[FileFullPath] 143 if not Repackage: 144 Logger.Error("\nMkPkg", 145 UPT_REPKG_ERROR, 146 ST.ERR_UPT_REPKG_ERROR, 147 ExtraData=ST.MSG_REPKG_CONFLICT %\ 148 (FileFullPath, DpGuid, DpVersion, DpName) 149 ) 150 else: 151 DistPkg.Header.RePackage = True 152 ContentFile.PackFile(FromFile) 153 chdir(Cwd) 154 155 # 156 # Add init dp information 157 # 158 else: 159 DistPkg = DistributionPackageClass() 160 DistPkg.Header.Name = 'Distribution Package' 161 DistPkg.Header.Guid = str(uuid4()) 162 DistPkg.Header.Version = '1.0' 163 164 DistPkg.GetDistributionPackage(WorkspaceDir, Options.PackageFileList, \ 165 Options.ModuleFileList) 166 FileList, MetaDataFileList = DistPkg.GetDistributionFileList() 167 for File in FileList + MetaDataFileList: 168 FileFullPath = os.path.normpath(os.path.join(WorkspaceDir, File)) 169 # 170 # check whether file was included in a distribution that can not 171 # be repackaged 172 # 173 if FileFullPath in RePkgDict: 174 (DpGuid, DpVersion, DpName, Repackage) = RePkgDict[FileFullPath] 175 if not Repackage: 176 Logger.Error("\nMkPkg", 177 UPT_REPKG_ERROR, 178 ST.ERR_UPT_REPKG_ERROR, 179 ExtraData = \ 180 ST.MSG_REPKG_CONFLICT %(FileFullPath, DpName, \ 181 DpGuid, DpVersion) 182 ) 183 else: 184 DistPkg.Header.RePackage = True 185 186 Cwd = getcwd() 187 chdir(WorkspaceDir) 188 ContentFile.PackFiles(FileList) 189 chdir(Cwd) 190 191 Logger.Verbose(ST.MSG_COMPRESS_DISTRIBUTION_PKG) 192 193 ContentFile.Close() 194 ContentFileClosed = True 195 196 # 197 # Add Md5Sigature 198 # 199 DistPkg.Header.Signature = md5.new(open(str(ContentFile), 'rb').read()).hexdigest() 200 # 201 # Add current Date 202 # 203 DistPkg.Header.Date = str(strftime("%Y-%m-%dT%H:%M:%S", localtime())) 204 205 # 206 # Finish final dp file 207 # 208 DistPkgFile = PackageFile(Options.PackFileToCreate, "w") 209 DistPkgFile.PackFile(str(ContentFile)) 210 DistPkgXml = DistributionPackageXml() 211 DistPkgFile.PackData(DistPkgXml.ToXml(DistPkg), GlobalData.gDESC_FILE) 212 DistPkgFile.Close() 213 Logger.Quiet(ST.MSG_FINISH) 214 ReturnCode = 0 215 216 except FatalError, XExcept: 217 ReturnCode = XExcept.args[0] 218 if Logger.GetLevel() <= Logger.DEBUG_9: 219 Logger.Quiet(ST.MSG_PYTHON_ON % \ 220 (python_version(), platform) + format_exc()) 221 except KeyboardInterrupt: 222 ReturnCode = ABORT_ERROR 223 if Logger.GetLevel() <= Logger.DEBUG_9: 224 Logger.Quiet(ST.MSG_PYTHON_ON % \ 225 (python_version(), platform) + format_exc()) 226 except OSError: 227 pass 228 except: 229 Logger.Error( 230 "\nMkPkg", 231 CODE_ERROR, 232 ST.ERR_UNKNOWN_FATAL_CREATING_ERR % \ 233 Options.PackFileToCreate, 234 ExtraData=ST.MSG_SEARCH_FOR_HELP, 235 RaiseError=False 236 ) 237 Logger.Quiet(ST.MSG_PYTHON_ON % \ 238 (python_version(), platform) + format_exc()) 239 ReturnCode = CODE_ERROR 240 finally: 241 if os.path.exists(GlobalData.gCONTENT_FILE): 242 if not ContentFileClosed: 243 ContentFile.Close() 244 os.remove(GlobalData.gCONTENT_FILE) 245 246 return ReturnCode 247 248 249## CheckFileList 250# 251# @param QualifiedExt: QualifiedExt 252# @param FileList: FileList 253# @param ErrorStringExt: ErrorStringExt 254# @param ErrorStringFullPath: ErrorStringFullPath 255# 256def CheckFileList(QualifiedExt, FileList, ErrorStringExt, ErrorStringFullPath): 257 if not FileList: 258 return 259 WorkspaceDir = GlobalData.gWORKSPACE 260 WorkspaceDir = os.path.normpath(WorkspaceDir) 261 for Item in FileList: 262 Ext = os.path.splitext(Item)[1] 263 if Ext.upper() != QualifiedExt.upper(): 264 Logger.Error("\nMkPkg", OPTION_VALUE_INVALID, \ 265 ErrorStringExt % Item) 266 267 Item = os.path.normpath(Item) 268 Path = mws.join(WorkspaceDir, Item) 269 if not os.path.exists(Path): 270 Logger.Error("\nMkPkg", FILE_NOT_FOUND, ST.ERR_NOT_FOUND % Item) 271 elif Item == Path: 272 Logger.Error("\nMkPkg", OPTION_VALUE_INVALID, 273 ErrorStringFullPath % Item) 274 elif not IsValidPath(Item, WorkspaceDir): 275 Logger.Error("\nMkPkg", OPTION_VALUE_INVALID, \ 276 ErrorStringExt % Item) 277 278 if not os.path.split(Item)[0]: 279 Logger.Error("\nMkPkg", OPTION_VALUE_INVALID, \ 280 ST.ERR_INVALID_METAFILE_PATH % Item) 281