1## @file 2# 3# This file is the main entry for UPT 4# 5# Copyright (c) 2011 - 2016, Intel Corporation. All rights reserved.<BR> 6# 7# This program and the accompanying materials are licensed and made available 8# under the terms and conditions of the BSD License which accompanies this 9# distribution. The full text of the license may be found at 10# http://opensource.org/licenses/bsd-license.php 11# 12# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 13# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 14# 15 16''' 17UPT 18''' 19 20## import modules 21# 22from Core import FileHook 23import sys 24import os.path 25from sys import platform 26import platform as pf 27from optparse import OptionParser 28from traceback import format_exc 29from platform import python_version 30 31from Logger import StringTable as ST 32import Logger.Log as Logger 33from Logger.StringTable import MSG_VERSION 34from Logger.StringTable import MSG_DESCRIPTION 35from Logger.StringTable import MSG_USAGE 36from Logger.ToolError import FILE_NOT_FOUND 37from Logger.ToolError import OPTION_MISSING 38from Logger.ToolError import FILE_TYPE_MISMATCH 39from Logger.ToolError import OPTION_CONFLICT 40from Logger.ToolError import FatalError 41from Logger.ToolError import UPT_ALREADY_INSTALLED_ERROR 42from Common.MultipleWorkspace import MultipleWorkspace as mws 43 44import MkPkg 45import InstallPkg 46import RmPkg 47import InventoryWs 48import ReplacePkg 49import TestInstall 50from Library.Misc import GetWorkspace 51from Library import GlobalData 52from Core.IpiDb import IpiDatabase 53from BuildVersion import gBUILD_VERSION 54 55## CheckConflictOption 56# 57# CheckConflictOption 58# 59def CheckConflictOption(Opt): 60 if (Opt.PackFileToCreate or Opt.PackFileToInstall or Opt.PackFileToRemove or Opt.PackFileToReplace) \ 61 and Opt.InventoryWs: 62 Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_L_OA_EXCLUSIVE) 63 elif Opt.PackFileToReplace and (Opt.PackFileToCreate or Opt.PackFileToInstall or Opt.PackFileToRemove): 64 Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_U_ICR_EXCLUSIVE) 65 elif (Opt.PackFileToCreate and Opt.PackFileToInstall and Opt.PackFileToRemove): 66 Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_REQUIRE_I_C_R_OPTION) 67 elif Opt.PackFileToCreate and Opt.PackFileToInstall: 68 Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_I_C_EXCLUSIVE) 69 elif Opt.PackFileToInstall and Opt.PackFileToRemove: 70 Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_I_R_EXCLUSIVE) 71 elif Opt.PackFileToCreate and Opt.PackFileToRemove: 72 Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_C_R_EXCLUSIVE) 73 elif Opt.TestDistFiles and (Opt.PackFileToCreate or Opt.PackFileToInstall \ 74 or Opt.PackFileToRemove or Opt.PackFileToReplace): 75 Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_C_R_EXCLUSIVE) 76 77 if Opt.CustomPath and Opt.UseGuidedPkgPath: 78 Logger.Warn("UPT", ST.WARN_CUSTOMPATH_OVERRIDE_USEGUIDEDPATH) 79 Opt.UseGuidedPkgPath = False 80 81## SetLogLevel 82# 83def SetLogLevel(Opt): 84 if Opt.opt_verbose: 85 Logger.SetLevel(Logger.VERBOSE) 86 elif Opt.opt_quiet: 87 Logger.SetLevel(Logger.QUIET + 1) 88 elif Opt.debug_level != None: 89 if Opt.debug_level < 0 or Opt.debug_level > 9: 90 Logger.Warn("UPT", ST.ERR_DEBUG_LEVEL) 91 Logger.SetLevel(Logger.INFO) 92 else: 93 Logger.SetLevel(Opt.debug_level + 1) 94 elif Opt.opt_slient: 95 Logger.SetLevel(Logger.SILENT) 96 else: 97 Logger.SetLevel(Logger.INFO) 98 99## Main 100# 101# Main 102# 103def Main(): 104 Logger.Initialize() 105 106 Parser = OptionParser(version=(MSG_VERSION + ' Build ' + gBUILD_VERSION), description=MSG_DESCRIPTION, 107 prog="UPT.exe", usage=MSG_USAGE) 108 109 Parser.add_option("-d", "--debug", action="store", type="int", dest="debug_level", help=ST.HLP_PRINT_DEBUG_INFO) 110 111 Parser.add_option("-v", "--verbose", action="store_true", dest="opt_verbose", 112 help=ST.HLP_PRINT_INFORMATIONAL_STATEMENT) 113 114 Parser.add_option("-s", "--silent", action="store_true", dest="opt_slient", help=ST.HLP_RETURN_NO_DISPLAY) 115 116 Parser.add_option("-q", "--quiet", action="store_true", dest="opt_quiet", help=ST.HLP_RETURN_AND_DISPLAY) 117 118 Parser.add_option("-i", "--install", action="store", type="string", dest="Install_Distribution_Package_File", 119 help=ST.HLP_SPECIFY_PACKAGE_NAME_INSTALL) 120 121 Parser.add_option("-c", "--create", action="store", type="string", dest="Create_Distribution_Package_File", 122 help=ST.HLP_SPECIFY_PACKAGE_NAME_CREATE) 123 124 Parser.add_option("-r", "--remove", action="store", type="string", dest="Remove_Distribution_Package_File", 125 help=ST.HLP_SPECIFY_PACKAGE_NAME_REMOVE) 126 127 Parser.add_option("-t", "--template", action="store", type="string", dest="Package_Information_Data_File", 128 help=ST.HLP_SPECIFY_TEMPLATE_NAME_CREATE) 129 130 Parser.add_option("-p", "--dec-filename", action="append", type="string", dest="EDK2_DEC_Filename", 131 help=ST.HLP_SPECIFY_DEC_NAME_CREATE) 132 133 Parser.add_option("-m", "--inf-filename", action="append", type="string", dest="EDK2_INF_Filename", 134 help=ST.HLP_SPECIFY_INF_NAME_CREATE) 135 136 Parser.add_option("-l", "--list", action="store_true", dest="List_Dist_Installed", 137 help=ST.HLP_LIST_DIST_INSTALLED) 138 139 Parser.add_option("-f", "--force", action="store_true", dest="Yes", help=ST.HLP_DISABLE_PROMPT) 140 141 Parser.add_option("-n", "--custom-path", action="store_true", dest="CustomPath", help=ST.HLP_CUSTOM_PATH_PROMPT) 142 143 Parser.add_option("-x", "--free-lock", action="store_true", dest="SkipLock", help=ST.HLP_SKIP_LOCK_CHECK) 144 145 Parser.add_option("-u", "--replace", action="store", type="string", dest="Replace_Distribution_Package_File", 146 help=ST.HLP_SPECIFY_PACKAGE_NAME_REPLACE) 147 148 Parser.add_option("-o", "--original", action="store", type="string", dest="Original_Distribution_Package_File", 149 help=ST.HLP_SPECIFY_PACKAGE_NAME_TO_BE_REPLACED) 150 151 Parser.add_option("--use-guided-paths", action="store_true", dest="Use_Guided_Paths", help=ST.HLP_USE_GUIDED_PATHS) 152 153 Parser.add_option("-j", "--test-install", action="append", type="string", 154 dest="Test_Install_Distribution_Package_Files", help=ST.HLP_TEST_INSTALL) 155 156 Opt = Parser.parse_args()[0] 157 158 Var2Var = [ 159 ("PackageInformationDataFile", Opt.Package_Information_Data_File), 160 ("PackFileToInstall", Opt.Install_Distribution_Package_File), 161 ("PackFileToCreate", Opt.Create_Distribution_Package_File), 162 ("PackFileToRemove", Opt.Remove_Distribution_Package_File), 163 ("PackageFileList", Opt.EDK2_DEC_Filename), 164 ("ModuleFileList", Opt.EDK2_INF_Filename), 165 ("InventoryWs", Opt.List_Dist_Installed), 166 ("PackFileToReplace", Opt.Replace_Distribution_Package_File), 167 ("PackFileToBeReplaced", Opt.Original_Distribution_Package_File), 168 ("UseGuidedPkgPath", Opt.Use_Guided_Paths), 169 ("TestDistFiles", Opt.Test_Install_Distribution_Package_Files) 170 ] 171 172 for Var in Var2Var: 173 setattr(Opt, Var[0], Var[1]) 174 175 try: 176 GlobalData.gWORKSPACE, GlobalData.gPACKAGE_PATH = GetWorkspace() 177 except FatalError, XExcept: 178 if Logger.GetLevel() <= Logger.DEBUG_9: 179 Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), platform) + format_exc()) 180 return XExcept.args[0] 181 182 # Start ********************************************* 183 # Support WORKSPACE is a long path 184 # Only work well on windows 185 # Linux Solution TBD 186 if pf.system() == 'Windows': 187 os.system('@echo off\nsubst b: /D') 188 os.system('subst b: "%s"' % GlobalData.gWORKSPACE) 189 GlobalData.gWORKSPACE = 'B:\\' 190 # End *********************************************** 191 192 WorkspaceDir = GlobalData.gWORKSPACE 193 194 SetLogLevel(Opt) 195 196 Mgr = FileHook.RecoverMgr(WorkspaceDir) 197 FileHook.SetRecoverMgr(Mgr) 198 199 GlobalData.gDB = IpiDatabase(os.path.normpath(os.path.join(WorkspaceDir, \ 200 "Conf/DistributionPackageDatabase.db")), WorkspaceDir) 201 GlobalData.gDB.InitDatabase(Opt.SkipLock) 202 203 # 204 # Make sure the Db will get closed correctly 205 # 206 try: 207 ReturnCode = 0 208 CheckConflictOption(Opt) 209 210 RunModule = None 211 if Opt.PackFileToCreate: 212 if Opt.PackageInformationDataFile: 213 if not os.path.exists(Opt.PackageInformationDataFile): 214 if not os.path.exists(os.path.join(WorkspaceDir, Opt.PackageInformationDataFile)): 215 Logger.Error("\nUPT", FILE_NOT_FOUND, ST.ERR_NO_TEMPLATE_FILE % Opt.PackageInformationDataFile) 216 else: 217 Opt.PackageInformationDataFile = os.path.join(WorkspaceDir, Opt.PackageInformationDataFile) 218 else: 219 Logger.Error("UPT", OPTION_MISSING, ExtraData=ST.ERR_REQUIRE_T_OPTION) 220 if not Opt.PackFileToCreate.endswith('.dist'): 221 Logger.Error("CreatePkg", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_EXT_ERROR % Opt.PackFileToCreate) 222 RunModule = MkPkg.Main 223 224 elif Opt.PackFileToInstall: 225 if not Opt.PackFileToInstall.endswith('.dist'): 226 Logger.Error("InstallPkg", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_EXT_ERROR % Opt.PackFileToInstall) 227 228 AbsPath = GetFullPathDist(Opt.PackFileToInstall, WorkspaceDir) 229 if not AbsPath: 230 Logger.Error("InstallPkg", FILE_NOT_FOUND, ST.ERR_INSTALL_DIST_NOT_FOUND % Opt.PackFileToInstall) 231 232 Opt.PackFileToInstall = AbsPath 233 setattr(Opt, 'PackageFile', Opt.PackFileToInstall) 234 RunModule = InstallPkg.Main 235 236 elif Opt.PackFileToRemove: 237 if not Opt.PackFileToRemove.endswith('.dist'): 238 Logger.Error("RemovePkg", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_EXT_ERROR % Opt.PackFileToRemove) 239 head, tail = os.path.split(Opt.PackFileToRemove) 240 if head or not tail: 241 Logger.Error("RemovePkg", 242 FILE_TYPE_MISMATCH, 243 ExtraData=ST.ERR_DIST_FILENAME_ONLY_FOR_REMOVE % Opt.PackFileToRemove) 244 245 setattr(Opt, 'DistributionFile', Opt.PackFileToRemove) 246 RunModule = RmPkg.Main 247 elif Opt.InventoryWs: 248 RunModule = InventoryWs.Main 249 250 elif Opt.PackFileToBeReplaced and not Opt.PackFileToReplace: 251 Logger.Error("ReplacePkg", OPTION_MISSING, ExtraData=ST.ERR_REQUIRE_U_OPTION) 252 253 elif Opt.PackFileToReplace: 254 if not Opt.PackFileToReplace.endswith('.dist'): 255 Logger.Error("ReplacePkg", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_EXT_ERROR % Opt.PackFileToReplace) 256 if not Opt.PackFileToBeReplaced: 257 Logger.Error("ReplacePkg", OPTION_MISSING, ExtraData=ST.ERR_REQUIRE_O_OPTION) 258 if not Opt.PackFileToBeReplaced.endswith('.dist'): 259 Logger.Error("ReplacePkg", 260 FILE_TYPE_MISMATCH, 261 ExtraData=ST.ERR_DIST_EXT_ERROR % Opt.PackFileToBeReplaced) 262 263 head, tail = os.path.split(Opt.PackFileToBeReplaced) 264 if head or not tail: 265 Logger.Error("ReplacePkg", 266 FILE_TYPE_MISMATCH, 267 ExtraData=ST.ERR_DIST_FILENAME_ONLY_FOR_REPLACE_ORIG % Opt.PackFileToBeReplaced) 268 269 AbsPath = GetFullPathDist(Opt.PackFileToReplace, WorkspaceDir) 270 if not AbsPath: 271 Logger.Error("ReplacePkg", FILE_NOT_FOUND, ST.ERR_REPLACE_DIST_NOT_FOUND % Opt.PackFileToReplace) 272 273 Opt.PackFileToReplace = AbsPath 274 RunModule = ReplacePkg.Main 275 276 elif Opt.Test_Install_Distribution_Package_Files: 277 for Dist in Opt.Test_Install_Distribution_Package_Files: 278 if not Dist.endswith('.dist'): 279 Logger.Error("TestInstall", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_EXT_ERROR % Dist) 280 281 setattr(Opt, 'DistFiles', Opt.Test_Install_Distribution_Package_Files) 282 RunModule = TestInstall.Main 283 284 else: 285 Parser.print_usage() 286 return OPTION_MISSING 287 288 ReturnCode = RunModule(Opt) 289 except FatalError, XExcept: 290 ReturnCode = XExcept.args[0] 291 if Logger.GetLevel() <= Logger.DEBUG_9: 292 Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), platform) + \ 293 format_exc()) 294 finally: 295 try: 296 if ReturnCode != 0 and ReturnCode != UPT_ALREADY_INSTALLED_ERROR: 297 Logger.Quiet(ST.MSG_RECOVER_START) 298 GlobalData.gDB.RollBack() 299 Mgr.rollback() 300 Logger.Quiet(ST.MSG_RECOVER_DONE) 301 else: 302 GlobalData.gDB.Commit() 303 Mgr.commit() 304 except StandardError: 305 Logger.Quiet(ST.MSG_RECOVER_FAIL) 306 GlobalData.gDB.CloseDb() 307 if pf.system() == 'Windows': 308 os.system('subst b: /D') 309 310 return ReturnCode 311 312## GetFullPathDist 313# 314# This function will check DistFile existence, if not absolute path, then try current working directory, 315# then $(WORKSPACE),and return the AbsPath. If file doesn't find, then return None 316# 317# @param DistFile: The distribution file in either relative path or absolute path 318# @param WorkspaceDir: Workspace Directory 319# @return AbsPath: The Absolute path of the distribution file if existed, None else 320# 321def GetFullPathDist(DistFile, WorkspaceDir): 322 if os.path.isabs(DistFile): 323 if not (os.path.exists(DistFile) and os.path.isfile(DistFile)): 324 return None 325 else: 326 return DistFile 327 else: 328 AbsPath = os.path.normpath(os.path.join(os.getcwd(), DistFile)) 329 if not (os.path.exists(AbsPath) and os.path.isfile(AbsPath)): 330 AbsPath = os.path.normpath(os.path.join(WorkspaceDir, DistFile)) 331 if not (os.path.exists(AbsPath) and os.path.isfile(AbsPath)): 332 return None 333 334 return AbsPath 335 336if __name__ == '__main__': 337 RETVAL = Main() 338 # 339 # 0-127 is a safe return range, and 1 is a standard default error 340 # 341 if RETVAL < 0 or RETVAL > 127: 342 RETVAL = 1 343 sys.exit(RETVAL) 344