summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/RmPkg.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/RmPkg.py')
-rwxr-xr-xsrc/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/RmPkg.py270
1 files changed, 270 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/RmPkg.py b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/RmPkg.py
new file mode 100755
index 00000000..98e0fcd6
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/BaseTools/Source/Python/UPT/RmPkg.py
@@ -0,0 +1,270 @@
+## @file
+# Install distribution package.
+#
+# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+
+'''
+RmPkg
+'''
+
+##
+# Import Modules
+#
+import os.path
+from stat import S_IWUSR
+from traceback import format_exc
+from platform import python_version
+from hashlib import md5
+from sys import stdin
+from sys import platform
+
+from Core.DependencyRules import DependencyRules
+from Library import GlobalData
+from Logger import StringTable as ST
+import Logger.Log as Logger
+from Logger.ToolError import OPTION_MISSING
+from Logger.ToolError import UNKNOWN_ERROR
+from Logger.ToolError import ABORT_ERROR
+from Logger.ToolError import CODE_ERROR
+from Logger.ToolError import FatalError
+
+
+## CheckDpDepex
+#
+# Check if the Depex is satisfied
+# @param Dep: Dep
+# @param Guid: Guid of Dp
+# @param Version: Version of Dp
+# @param WorkspaceDir: Workspace Dir
+#
+def CheckDpDepex(Dep, Guid, Version, WorkspaceDir):
+ (Removable, DependModuleList) = Dep.CheckDpDepexForRemove(Guid, Version)
+ if not Removable:
+ Logger.Info(ST.MSG_CONFIRM_REMOVE)
+ Logger.Info(ST.MSG_USER_DELETE_OP)
+ Input = stdin.readline()
+ Input = Input.replace('\r', '').replace('\n', '')
+ if Input.upper() != 'Y':
+ Logger.Error("RmPkg", UNKNOWN_ERROR, ST.ERR_USER_INTERRUPT)
+ return 1
+ else:
+ #
+ # report list of modules that are not valid due to force
+ # remove,
+ # also generate a log file for reference
+ #
+ Logger.Info(ST.MSG_INVALID_MODULE_INTRODUCED)
+ LogFilePath = os.path.normpath(os.path.join(WorkspaceDir, GlobalData.gINVALID_MODULE_FILE))
+ Logger.Info(ST.MSG_CHECK_LOG_FILE % LogFilePath)
+ try:
+ LogFile = open(LogFilePath, 'w')
+ try:
+ for ModulePath in DependModuleList:
+ LogFile.write("%s\n"%ModulePath)
+ Logger.Info(ModulePath)
+ except IOError:
+ Logger.Warn("\nRmPkg", ST.ERR_FILE_WRITE_FAILURE,
+ File=LogFilePath)
+ except IOError:
+ Logger.Warn("\nRmPkg", ST.ERR_FILE_OPEN_FAILURE,
+ File=LogFilePath)
+ finally:
+ LogFile.close()
+
+## Remove Path
+#
+# removing readonly file on windows will get "Access is denied"
+# error, so before removing, change the mode to be writeable
+#
+# @param Path: The Path to be removed
+#
+def RemovePath(Path):
+ Logger.Info(ST.MSG_REMOVE_FILE % Path)
+ if not os.access(Path, os.W_OK):
+ os.chmod(Path, S_IWUSR)
+ os.remove(Path)
+ try:
+ os.removedirs(os.path.split(Path)[0])
+ except OSError:
+ pass
+## GetCurrentFileList
+#
+# @param DataBase: DataBase of UPT
+# @param Guid: Guid of Dp
+# @param Version: Version of Dp
+# @param WorkspaceDir: Workspace Dir
+#
+def GetCurrentFileList(DataBase, Guid, Version, WorkspaceDir):
+ NewFileList = []
+ for Dir in DataBase.GetDpInstallDirList(Guid, Version):
+ RootDir = os.path.normpath(os.path.join(WorkspaceDir, Dir))
+ for Root, Dirs, Files in os.walk(RootDir):
+ Logger.Debug(0, Dirs)
+ for File in Files:
+ FilePath = os.path.join(Root, File)
+ if FilePath not in NewFileList:
+ NewFileList.append(FilePath)
+ return NewFileList
+
+
+## Tool entrance method
+#
+# This method mainly dispatch specific methods per the command line options.
+# If no error found, return zero value so the caller of this tool can know
+# if it's executed successfully or not.
+#
+# @param Options: command option
+#
+def Main(Options = None):
+
+ try:
+ DataBase = GlobalData.gDB
+ if not Options.DistributionFile:
+ Logger.Error("RmPkg",
+ OPTION_MISSING,
+ ExtraData=ST.ERR_SPECIFY_PACKAGE)
+ WorkspaceDir = GlobalData.gWORKSPACE
+ #
+ # Prepare check dependency
+ #
+ Dep = DependencyRules(DataBase)
+
+ #
+ # Get the Dp information
+ #
+ StoredDistFile, Guid, Version = GetInstalledDpInfo(Options.DistributionFile, Dep, DataBase, WorkspaceDir)
+
+ #
+ # Check Dp depex
+ #
+ CheckDpDepex(Dep, Guid, Version, WorkspaceDir)
+
+ #
+ # remove distribution
+ #
+ RemoveDist(Guid, Version, StoredDistFile, DataBase, WorkspaceDir, Options.Yes)
+
+ Logger.Quiet(ST.MSG_FINISH)
+
+ ReturnCode = 0
+
+ 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())
+ except KeyboardInterrupt:
+ ReturnCode = ABORT_ERROR
+ if Logger.GetLevel() <= Logger.DEBUG_9:
+ Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), platform) + \
+ format_exc())
+ except:
+ Logger.Error(
+ "\nRmPkg",
+ CODE_ERROR,
+ ST.ERR_UNKNOWN_FATAL_REMOVING_ERR,
+ ExtraData=ST.MSG_SEARCH_FOR_HELP % ST.MSG_EDKII_MAIL_ADDR,
+ RaiseError=False
+ )
+ Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), platform) + \
+ format_exc())
+ ReturnCode = CODE_ERROR
+ return ReturnCode
+
+## GetInstalledDpInfo method
+#
+# Get the installed distribution information
+#
+# @param DistributionFile: the name of the distribution
+# @param Dep: the instance of DependencyRules
+# @param DataBase: the internal database
+# @param WorkspaceDir: work space directory
+# @retval StoredDistFile: the distribution file that backed up
+# @retval Guid: the Guid of the distribution
+# @retval Version: the Version of distribution
+#
+def GetInstalledDpInfo(DistributionFile, Dep, DataBase, WorkspaceDir):
+ (Guid, Version, NewDpFileName) = DataBase.GetDpByName(os.path.split(DistributionFile)[1])
+ if not Guid:
+ Logger.Error("RmPkg", UNKNOWN_ERROR, ST.ERR_PACKAGE_NOT_INSTALLED % DistributionFile)
+
+ #
+ # Check Dp existing
+ #
+ if not Dep.CheckDpExists(Guid, Version):
+ Logger.Error("RmPkg", UNKNOWN_ERROR, ST.ERR_DISTRIBUTION_NOT_INSTALLED)
+ #
+ # Check for Distribution files existence in /conf/upt, if not exist,
+ # Warn user and go on.
+ #
+ StoredDistFile = os.path.normpath(os.path.join(WorkspaceDir, GlobalData.gUPT_DIR, NewDpFileName))
+ if not os.path.isfile(StoredDistFile):
+ Logger.Warn("RmPkg", ST.WRN_DIST_NOT_FOUND%StoredDistFile)
+ StoredDistFile = None
+
+ return StoredDistFile, Guid, Version
+
+## RemoveDist method
+#
+# remove a distribution
+#
+# @param Guid: the Guid of the distribution
+# @param Version: the Version of distribution
+# @param StoredDistFile: the distribution file that backed up
+# @param DataBase: the internal database
+# @param WorkspaceDir: work space directory
+# @param ForceRemove: whether user want to remove file even it is modified
+#
+def RemoveDist(Guid, Version, StoredDistFile, DataBase, WorkspaceDir, ForceRemove):
+ #
+ # Get Current File List
+ #
+ NewFileList = GetCurrentFileList(DataBase, Guid, Version, WorkspaceDir)
+
+ #
+ # Remove all files
+ #
+ MissingFileList = []
+ for (Path, Md5Sum) in DataBase.GetDpFileList(Guid, Version):
+ if os.path.isfile(Path):
+ if Path in NewFileList:
+ NewFileList.remove(Path)
+ if not ForceRemove:
+ #
+ # check whether modified by users
+ #
+ Md5Signature = md5(open(str(Path), 'rb').read())
+ if Md5Sum != Md5Signature.hexdigest():
+ Logger.Info(ST.MSG_CONFIRM_REMOVE2 % Path)
+ Input = stdin.readline()
+ Input = Input.replace('\r', '').replace('\n', '')
+ if Input.upper() != 'Y':
+ continue
+ RemovePath(Path)
+ else:
+ MissingFileList.append(Path)
+
+ for Path in NewFileList:
+ if os.path.isfile(Path):
+ if (not ForceRemove) and (not os.path.split(Path)[1].startswith('.')):
+ Logger.Info(ST.MSG_CONFIRM_REMOVE3 % Path)
+ Input = stdin.readline()
+ Input = Input.replace('\r', '').replace('\n', '')
+ if Input.upper() != 'Y':
+ continue
+ RemovePath(Path)
+
+ #
+ # Remove distribution files in /Conf/.upt
+ #
+ if StoredDistFile is not None:
+ os.remove(StoredDistFile)
+
+ #
+ # update database
+ #
+ Logger.Quiet(ST.MSG_UPDATE_PACKAGE_DATABASE)
+ DataBase.RemoveDpObj(Guid, Version)