## @file # # This file is the main entry for UPT # # Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent # ''' UPT ''' ## import modules # import locale import sys from imp import reload encoding = locale.getdefaultlocale()[1] if encoding: reload(sys) sys.setdefaultencoding(encoding) from Core import FileHook import os.path from sys import platform import platform as pf from optparse import OptionParser from traceback import format_exc from platform import python_version from Logger import StringTable as ST import Logger.Log as Logger from Logger.StringTable import MSG_VERSION from Logger.StringTable import MSG_DESCRIPTION from Logger.StringTable import MSG_USAGE from Logger.ToolError import FILE_NOT_FOUND from Logger.ToolError import OPTION_MISSING from Logger.ToolError import FILE_TYPE_MISMATCH from Logger.ToolError import OPTION_CONFLICT from Logger.ToolError import FatalError from Logger.ToolError import UPT_ALREADY_INSTALLED_ERROR from Common.MultipleWorkspace import MultipleWorkspace as mws import MkPkg import InstallPkg import RmPkg import InventoryWs import ReplacePkg import TestInstall from Library.Misc import GetWorkspace from Library import GlobalData from Core.IpiDb import IpiDatabase from BuildVersion import gBUILD_VERSION ## CheckConflictOption # # CheckConflictOption # def CheckConflictOption(Opt): if (Opt.PackFileToCreate or Opt.PackFileToInstall or Opt.PackFileToRemove or Opt.PackFileToReplace) \ and Opt.InventoryWs: Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_L_OA_EXCLUSIVE) elif Opt.PackFileToReplace and (Opt.PackFileToCreate or Opt.PackFileToInstall or Opt.PackFileToRemove): Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_U_ICR_EXCLUSIVE) elif (Opt.PackFileToCreate and Opt.PackFileToInstall and Opt.PackFileToRemove): Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_REQUIRE_I_C_R_OPTION) elif Opt.PackFileToCreate and Opt.PackFileToInstall: Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_I_C_EXCLUSIVE) elif Opt.PackFileToInstall and Opt.PackFileToRemove: Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_I_R_EXCLUSIVE) elif Opt.PackFileToCreate and Opt.PackFileToRemove: Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_C_R_EXCLUSIVE) elif Opt.TestDistFiles and (Opt.PackFileToCreate or Opt.PackFileToInstall \ or Opt.PackFileToRemove or Opt.PackFileToReplace): Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_C_R_EXCLUSIVE) if Opt.CustomPath and Opt.UseGuidedPkgPath: Logger.Warn("UPT", ST.WARN_CUSTOMPATH_OVERRIDE_USEGUIDEDPATH) Opt.UseGuidedPkgPath = False ## SetLogLevel # def SetLogLevel(Opt): if Opt.opt_verbose: Logger.SetLevel(Logger.VERBOSE) elif Opt.opt_quiet: Logger.SetLevel(Logger.QUIET + 1) elif Opt.debug_level is not None: if Opt.debug_level < 0 or Opt.debug_level > 9: Logger.Warn("UPT", ST.ERR_DEBUG_LEVEL) Logger.SetLevel(Logger.INFO) else: Logger.SetLevel(Opt.debug_level + 1) elif Opt.opt_slient: Logger.SetLevel(Logger.SILENT) else: Logger.SetLevel(Logger.INFO) ## Main # # Main # def Main(): Logger.Initialize() Parser = OptionParser(version=(MSG_VERSION + ' Build ' + gBUILD_VERSION), description=MSG_DESCRIPTION, prog="UPT.exe", usage=MSG_USAGE) Parser.add_option("-d", "--debug", action="store", type="int", dest="debug_level", help=ST.HLP_PRINT_DEBUG_INFO) Parser.add_option("-v", "--verbose", action="store_true", dest="opt_verbose", help=ST.HLP_PRINT_INFORMATIONAL_STATEMENT) Parser.add_option("-s", "--silent", action="store_true", dest="opt_slient", help=ST.HLP_RETURN_NO_DISPLAY) Parser.add_option("-q", "--quiet", action="store_true", dest="opt_quiet", help=ST.HLP_RETURN_AND_DISPLAY) Parser.add_option("-i", "--install", action="append", type="string", dest="Install_Distribution_Package_File", help=ST.HLP_SPECIFY_PACKAGE_NAME_INSTALL) Parser.add_option("-c", "--create", action="store", type="string", dest="Create_Distribution_Package_File", help=ST.HLP_SPECIFY_PACKAGE_NAME_CREATE) Parser.add_option("-r", "--remove", action="store", type="string", dest="Remove_Distribution_Package_File", help=ST.HLP_SPECIFY_PACKAGE_NAME_REMOVE) Parser.add_option("-t", "--template", action="store", type="string", dest="Package_Information_Data_File", help=ST.HLP_SPECIFY_TEMPLATE_NAME_CREATE) Parser.add_option("-p", "--dec-filename", action="append", type="string", dest="EDK2_DEC_Filename", help=ST.HLP_SPECIFY_DEC_NAME_CREATE) Parser.add_option("-m", "--inf-filename", action="append", type="string", dest="EDK2_INF_Filename", help=ST.HLP_SPECIFY_INF_NAME_CREATE) Parser.add_option("-l", "--list", action="store_true", dest="List_Dist_Installed", help=ST.HLP_LIST_DIST_INSTALLED) Parser.add_option("-f", "--force", action="store_true", dest="Yes", help=ST.HLP_DISABLE_PROMPT) Parser.add_option("-n", "--custom-path", action="store_true", dest="CustomPath", help=ST.HLP_CUSTOM_PATH_PROMPT) Parser.add_option("-x", "--free-lock", action="store_true", dest="SkipLock", help=ST.HLP_SKIP_LOCK_CHECK) Parser.add_option("-u", "--replace", action="store", type="string", dest="Replace_Distribution_Package_File", help=ST.HLP_SPECIFY_PACKAGE_NAME_REPLACE) Parser.add_option("-o", "--original", action="store", type="string", dest="Original_Distribution_Package_File", help=ST.HLP_SPECIFY_PACKAGE_NAME_TO_BE_REPLACED) Parser.add_option("--use-guided-paths", action="store_true", dest="Use_Guided_Paths", help=ST.HLP_USE_GUIDED_PATHS) Parser.add_option("-j", "--test-install", action="append", type="string", dest="Test_Install_Distribution_Package_Files", help=ST.HLP_TEST_INSTALL) Opt = Parser.parse_args()[0] Var2Var = [ ("PackageInformationDataFile", Opt.Package_Information_Data_File), ("PackFileToInstall", Opt.Install_Distribution_Package_File), ("PackFileToCreate", Opt.Create_Distribution_Package_File), ("PackFileToRemove", Opt.Remove_Distribution_Package_File), ("PackageFileList", Opt.EDK2_DEC_Filename), ("ModuleFileList", Opt.EDK2_INF_Filename), ("InventoryWs", Opt.List_Dist_Installed), ("PackFileToReplace", Opt.Replace_Distribution_Package_File), ("PackFileToBeReplaced", Opt.Original_Distribution_Package_File), ("UseGuidedPkgPath", Opt.Use_Guided_Paths), ("TestDistFiles", Opt.Test_Install_Distribution_Package_Files) ] for Var in Var2Var: setattr(Opt, Var[0], Var[1]) try: GlobalData.gWORKSPACE, GlobalData.gPACKAGE_PATH = GetWorkspace() except FatalError as XExcept: if Logger.GetLevel() <= Logger.DEBUG_9: Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), platform) + format_exc()) return XExcept.args[0] # Support WORKSPACE is a long path # Only works for windows system if pf.system() == 'Windows': Vol = 'B:' for Index in range(90, 65, -1): Vol = chr(Index) + ':' if not os.path.isdir(Vol): os.system('subst %s "%s"' % (Vol, GlobalData.gWORKSPACE)) break GlobalData.gWORKSPACE = '%s\\' % Vol WorkspaceDir = GlobalData.gWORKSPACE SetLogLevel(Opt) Mgr = FileHook.RecoverMgr(WorkspaceDir) FileHook.SetRecoverMgr(Mgr) GlobalData.gDB = IpiDatabase(os.path.normpath(os.path.join(WorkspaceDir, \ "Conf/DistributionPackageDatabase.db")), WorkspaceDir) GlobalData.gDB.InitDatabase(Opt.SkipLock) # # Make sure the Db will get closed correctly # try: ReturnCode = 0 CheckConflictOption(Opt) RunModule = None if Opt.PackFileToCreate: if Opt.PackageInformationDataFile: if not os.path.exists(Opt.PackageInformationDataFile): if not os.path.exists(os.path.join(WorkspaceDir, Opt.PackageInformationDataFile)): Logger.Error("\nUPT", FILE_NOT_FOUND, ST.ERR_NO_TEMPLATE_FILE % Opt.PackageInformationDataFile) else: Opt.PackageInformationDataFile = os.path.join(WorkspaceDir, Opt.PackageInformationDataFile) else: Logger.Error("UPT", OPTION_MISSING, ExtraData=ST.ERR_REQUIRE_T_OPTION) if not Opt.PackFileToCreate.endswith('.dist'): Logger.Error("CreatePkg", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_EXT_ERROR % Opt.PackFileToCreate) RunModule = MkPkg.Main elif Opt.PackFileToInstall: AbsPath = [] for Item in Opt.PackFileToInstall: if not Item.endswith('.dist'): Logger.Error("InstallPkg", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_EXT_ERROR % Item) AbsPath.append(GetFullPathDist(Item, WorkspaceDir)) if not AbsPath: Logger.Error("InstallPkg", FILE_NOT_FOUND, ST.ERR_INSTALL_DIST_NOT_FOUND % Item) Opt.PackFileToInstall = AbsPath setattr(Opt, 'PackageFile', Opt.PackFileToInstall) RunModule = InstallPkg.Main elif Opt.PackFileToRemove: if not Opt.PackFileToRemove.endswith('.dist'): Logger.Error("RemovePkg", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_EXT_ERROR % Opt.PackFileToRemove) head, tail = os.path.split(Opt.PackFileToRemove) if head or not tail: Logger.Error("RemovePkg", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_FILENAME_ONLY_FOR_REMOVE % Opt.PackFileToRemove) setattr(Opt, 'DistributionFile', Opt.PackFileToRemove) RunModule = RmPkg.Main elif Opt.InventoryWs: RunModule = InventoryWs.Main elif Opt.PackFileToBeReplaced and not Opt.PackFileToReplace: Logger.Error("ReplacePkg", OPTION_MISSING, ExtraData=ST.ERR_REQUIRE_U_OPTION) elif Opt.PackFileToReplace: if not Opt.PackFileToReplace.endswith('.dist'): Logger.Error("ReplacePkg", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_EXT_ERROR % Opt.PackFileToReplace) if not Opt.PackFileToBeReplaced: Logger.Error("ReplacePkg", OPTION_MISSING, ExtraData=ST.ERR_REQUIRE_O_OPTION) if not Opt.PackFileToBeReplaced.endswith('.dist'): Logger.Error("ReplacePkg", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_EXT_ERROR % Opt.PackFileToBeReplaced) head, tail = os.path.split(Opt.PackFileToBeReplaced) if head or not tail: Logger.Error("ReplacePkg", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_FILENAME_ONLY_FOR_REPLACE_ORIG % Opt.PackFileToBeReplaced) AbsPath = GetFullPathDist(Opt.PackFileToReplace, WorkspaceDir) if not AbsPath: Logger.Error("ReplacePkg", FILE_NOT_FOUND, ST.ERR_REPLACE_DIST_NOT_FOUND % Opt.PackFileToReplace) Opt.PackFileToReplace = AbsPath RunModule = ReplacePkg.Main elif Opt.Test_Install_Distribution_Package_Files: for Dist in Opt.Test_Install_Distribution_Package_Files: if not Dist.endswith('.dist'): Logger.Error("TestInstall", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_EXT_ERROR % Dist) setattr(Opt, 'DistFiles', Opt.Test_Install_Distribution_Package_Files) RunModule = TestInstall.Main else: Parser.print_usage() return OPTION_MISSING ReturnCode = RunModule(Opt) except FatalError as XExcept: ReturnCode = XExcept.args[0] if Logger.GetLevel() <= Logger.DEBUG_9: Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), platform) + \ format_exc()) finally: try: if ReturnCode != 0 and ReturnCode != UPT_ALREADY_INSTALLED_ERROR: Logger.Quiet(ST.MSG_RECOVER_START) GlobalData.gDB.RollBack() Mgr.rollback() Logger.Quiet(ST.MSG_RECOVER_DONE) else: GlobalData.gDB.Commit() Mgr.commit() except Exception: Logger.Quiet(ST.MSG_RECOVER_FAIL) GlobalData.gDB.CloseDb() if pf.system() == 'Windows': os.system('subst %s /D' % GlobalData.gWORKSPACE.replace('\\', '')) return ReturnCode ## GetFullPathDist # # This function will check DistFile existence, if not absolute path, then try current working directory, # then $(WORKSPACE),and return the AbsPath. If file doesn't find, then return None # # @param DistFile: The distribution file in either relative path or absolute path # @param WorkspaceDir: Workspace Directory # @return AbsPath: The Absolute path of the distribution file if existed, None else # def GetFullPathDist(DistFile, WorkspaceDir): if os.path.isabs(DistFile): if not (os.path.exists(DistFile) and os.path.isfile(DistFile)): return None else: return DistFile else: AbsPath = os.path.normpath(os.path.join(os.getcwd(), DistFile)) if not (os.path.exists(AbsPath) and os.path.isfile(AbsPath)): AbsPath = os.path.normpath(os.path.join(WorkspaceDir, DistFile)) if not (os.path.exists(AbsPath) and os.path.isfile(AbsPath)): return None return AbsPath if __name__ == '__main__': RETVAL = Main() # # 0-127 is a safe return range, and 1 is a standard default error # if RETVAL < 0 or RETVAL > 127: RETVAL = 1 sys.exit(RETVAL)