summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UPT.py
diff options
context:
space:
mode:
Diffstat (limited to '')
-rwxr-xr-xsrc/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UPT.py347
1 files changed, 347 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UPT.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UPT.py
new file mode 100755
index 00000000..693e01e0
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/UPT.py
@@ -0,0 +1,347 @@
+## @file
+#
+# This file is the main entry for UPT
+#
+# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# 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)