mirror of
				https://git.proxmox.com/git/mirror_edk2
				synced 2025-10-31 07:17:27 +00:00 
			
		
		
		
	 4234283c3a
			
		
	
	
		4234283c3a
		
	
	
	
	
		
			
			BaseTool Branch: https://edk2-buildtools.svn.sourceforge.net/svnroot/edk2-buildtools/branches/Releases/BaseTools_r2100 Signed-off-by: lgao4 Reviewed-by: hchen30 git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12214 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			247 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			247 lines
		
	
	
		
			8.4 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| ## @file
 | |
| # Install distribution package.
 | |
| #
 | |
| # Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
 | |
| #
 | |
| # This program and the accompanying materials are licensed and made available 
 | |
| # under the terms and conditions of the BSD License which accompanies this 
 | |
| # distribution. The full text of the license may be found at 
 | |
| # http://opensource.org/licenses/bsd-license.php
 | |
| #
 | |
| # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | |
| # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | |
| #
 | |
| 
 | |
| '''
 | |
| RmPkg
 | |
| '''
 | |
| 
 | |
| ##
 | |
| # Import Modules
 | |
| #
 | |
| import os.path
 | |
| from stat import S_IWUSR
 | |
| from traceback import format_exc
 | |
| from platform import python_version
 | |
| import md5
 | |
| from sys import stdin
 | |
| from sys import platform
 | |
| 
 | |
| from Core.DependencyRules import DependencyRules
 | |
| from Library.Misc import CheckEnvVariable
 | |
| 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)
 | |
|         CheckEnvVariable()
 | |
|         WorkspaceDir = GlobalData.gWORKSPACE
 | |
|         #
 | |
|         # Prepare check dependency
 | |
|         #
 | |
|         Dep = DependencyRules(DataBase)
 | |
|         
 | |
|         if Options.DistributionFile:
 | |
|             (Guid, Version, NewDpFileName) = \
 | |
|             DataBase.GetDpByName(os.path.split(Options.DistributionFile)[1])
 | |
|             if not Guid:
 | |
|                 Logger.Error("RmPkg", UNKNOWN_ERROR, ST.ERR_PACKAGE_NOT_INSTALLED % Options.DistributionFile)
 | |
|         else:
 | |
|             Guid = Options.PackageGuid
 | |
|             Version = Options.PackageVersion
 | |
|         #
 | |
|         # 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
 | |
|             
 | |
|         # 
 | |
|         # Check Dp depex
 | |
|         #
 | |
|         CheckDpDepex(Dep, Guid, Version, WorkspaceDir)
 | |
| 
 | |
|         #
 | |
|         # 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 Options.Yes:
 | |
|                     #
 | |
|                     # check whether modified by users
 | |
|                     #
 | |
|                     Md5Sigature = md5.new(open(str(Path), 'rb').read())
 | |
|                     if Md5Sum != Md5Sigature.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 Options.Yes) 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)
 | |
|         Logger.Quiet(ST.MSG_FINISH)
 | |
|         
 | |
|         ReturnCode = 0
 | |
|         
 | |
|     except FatalError, 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,
 | |
|                     RaiseError=False
 | |
|                     )
 | |
|         Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), platform) + \
 | |
|                      format_exc())
 | |
|         ReturnCode = CODE_ERROR
 | |
|     return ReturnCode
 | |
|         
 | |
| 
 |