| ## @file | |
| # Replace distribution package. | |
| # | |
| # Copyright (c) 2014, 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. | |
| # | |
| """ | |
| Replace a distribution package | |
| """ | |
| ## | |
| # Import Modules | |
| # | |
| from shutil import rmtree | |
| from traceback import format_exc | |
| from platform import python_version | |
| from sys import platform | |
| from Logger import StringTable as ST | |
| from Logger.ToolError import UNKNOWN_ERROR | |
| from Logger.ToolError import FatalError | |
| from Logger.ToolError import ABORT_ERROR | |
| from Logger.ToolError import CODE_ERROR | |
| from Logger.ToolError import UPT_ALREADY_INSTALLED_ERROR | |
| import Logger.Log as Logger | |
| from Core.DependencyRules import DependencyRules | |
| from Library import GlobalData | |
| from InstallPkg import UnZipDp | |
| from InstallPkg import InstallDp | |
| from RmPkg import GetInstalledDpInfo | |
| from RmPkg import RemoveDist | |
| ## 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 Options | |
| # | |
| def Main(Options = None): | |
| ContentZipFile, DistFile = None, None | |
| try: | |
| DataBase = GlobalData.gDB | |
| WorkspaceDir = GlobalData.gWORKSPACE | |
| Dep = DependencyRules(DataBase) | |
| DistPkg, ContentZipFile, DpPkgFileName, DistFile = UnZipDp(WorkspaceDir, Options.PackFileToReplace) | |
| StoredDistFile, OrigDpGuid, OrigDpVersion = GetInstalledDpInfo(Options.PackFileToBeReplaced, \ | |
| Dep, DataBase, WorkspaceDir) | |
| # | |
| # check dependency | |
| # | |
| CheckReplaceDpx(Dep, DistPkg, OrigDpGuid, OrigDpVersion) | |
| # | |
| # Remove the old distribution | |
| # | |
| RemoveDist(OrigDpGuid, OrigDpVersion, StoredDistFile, DataBase, WorkspaceDir, Options.Yes) | |
| # | |
| # Install the new distribution | |
| # | |
| InstallDp(DistPkg, DpPkgFileName, ContentZipFile, Options, Dep, WorkspaceDir, DataBase) | |
| 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: | |
| ReturnCode = CODE_ERROR | |
| Logger.Error( | |
| "\nReplacePkg", | |
| CODE_ERROR, | |
| ST.ERR_UNKNOWN_FATAL_REPLACE_ERR % (Options.PackFileToReplace, Options.PackFileToBeReplaced), | |
| ExtraData=ST.MSG_SEARCH_FOR_HELP, | |
| RaiseError=False | |
| ) | |
| Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), | |
| platform) + format_exc()) | |
| finally: | |
| Logger.Quiet(ST.MSG_REMOVE_TEMP_FILE_STARTED) | |
| if DistFile: | |
| DistFile.Close() | |
| if ContentZipFile: | |
| ContentZipFile.Close() | |
| if GlobalData.gUNPACK_DIR: | |
| rmtree(GlobalData.gUNPACK_DIR) | |
| GlobalData.gUNPACK_DIR = None | |
| Logger.Quiet(ST.MSG_REMOVE_TEMP_FILE_DONE) | |
| if ReturnCode == 0: | |
| Logger.Quiet(ST.MSG_FINISH) | |
| return ReturnCode | |
| def CheckReplaceDpx(Dep, DistPkg, OrigDpGuid, OrigDpVersion): | |
| NewDpPkgList = [] | |
| for PkgInfo in DistPkg.PackageSurfaceArea: | |
| Guid, Version = PkgInfo[0], PkgInfo[1] | |
| NewDpPkgList.append((Guid, Version)) | |
| NewDpInfo = "%s %s" % (DistPkg.Header.GetGuid(), DistPkg.Header.GetVersion()) | |
| OrigDpInfo = "%s %s" % (OrigDpGuid, OrigDpVersion) | |
| # | |
| # check whether new distribution is already installed and not replacing itself | |
| # | |
| if (NewDpInfo != OrigDpInfo): | |
| if Dep.CheckDpExists(DistPkg.Header.GetGuid(), DistPkg.Header.GetVersion()): | |
| Logger.Error("\nReplacePkg", UPT_ALREADY_INSTALLED_ERROR, | |
| ST.WRN_DIST_PKG_INSTALLED, | |
| ExtraData=ST.MSG_REPLACE_ALREADY_INSTALLED_DP) | |
| # | |
| # check whether the original distribution could be replaced by new distribution | |
| # | |
| Logger.Verbose(ST.MSG_CHECK_DP_FOR_REPLACE%(NewDpInfo, OrigDpInfo)) | |
| DepInfoResult = Dep.CheckDpDepexForReplace(OrigDpGuid, OrigDpVersion, NewDpPkgList) | |
| Replaceable = DepInfoResult[0] | |
| if not Replaceable: | |
| Logger.Error("\nReplacePkg", UNKNOWN_ERROR, | |
| ST.ERR_PACKAGE_NOT_MATCH_DEPENDENCY) | |
| # | |
| # check whether new distribution could be installed by dependency rule | |
| # | |
| Logger.Verbose(ST.MSG_CHECK_DP_FOR_INSTALL%str(NewDpInfo)) | |
| if not Dep.ReplaceCheckNewDpDepex(DistPkg, OrigDpGuid, OrigDpVersion): | |
| Logger.Error("\nReplacePkg", UNKNOWN_ERROR, | |
| ST.ERR_PACKAGE_NOT_MATCH_DEPENDENCY, | |
| ExtraData=DistPkg.Header.Name) | |