1## @file 2# Replace distribution package. 3# 4# Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR> 5# 6# SPDX-License-Identifier: BSD-2-Clause-Patent 7# 8""" 9Replace a distribution package 10""" 11## 12# Import Modules 13# 14from shutil import rmtree 15from traceback import format_exc 16from platform import python_version 17from sys import platform 18from Logger import StringTable as ST 19from Logger.ToolError import UNKNOWN_ERROR 20from Logger.ToolError import FatalError 21from Logger.ToolError import ABORT_ERROR 22from Logger.ToolError import CODE_ERROR 23from Logger.ToolError import UPT_ALREADY_INSTALLED_ERROR 24import Logger.Log as Logger 25 26from Core.DependencyRules import DependencyRules 27from Library import GlobalData 28from InstallPkg import UnZipDp 29from InstallPkg import InstallDp 30from RmPkg import GetInstalledDpInfo 31from RmPkg import RemoveDist 32 33## Tool entrance method 34# 35# This method mainly dispatch specific methods per the command line options. 36# If no error found, return zero value so the caller of this tool can know 37# if it's executed successfully or not. 38# 39# @param Options: command Options 40# 41def Main(Options = None): 42 ContentZipFile, DistFile = None, None 43 try: 44 DataBase = GlobalData.gDB 45 WorkspaceDir = GlobalData.gWORKSPACE 46 Dep = DependencyRules(DataBase) 47 DistPkg, ContentZipFile, DpPkgFileName, DistFile = UnZipDp(WorkspaceDir, Options.PackFileToReplace) 48 49 StoredDistFile, OrigDpGuid, OrigDpVersion = GetInstalledDpInfo(Options.PackFileToBeReplaced, \ 50 Dep, DataBase, WorkspaceDir) 51 52 # 53 # check dependency 54 # 55 CheckReplaceDpx(Dep, DistPkg, OrigDpGuid, OrigDpVersion) 56 57 # 58 # Remove the old distribution 59 # 60 RemoveDist(OrigDpGuid, OrigDpVersion, StoredDistFile, DataBase, WorkspaceDir, Options.Yes) 61 62 # 63 # Install the new distribution 64 # 65 InstallDp(DistPkg, DpPkgFileName, ContentZipFile, Options, Dep, WorkspaceDir, DataBase) 66 ReturnCode = 0 67 68 except FatalError as XExcept: 69 ReturnCode = XExcept.args[0] 70 if Logger.GetLevel() <= Logger.DEBUG_9: 71 Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), 72 platform) + format_exc()) 73 except KeyboardInterrupt: 74 ReturnCode = ABORT_ERROR 75 if Logger.GetLevel() <= Logger.DEBUG_9: 76 Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), 77 platform) + format_exc()) 78 except: 79 ReturnCode = CODE_ERROR 80 Logger.Error( 81 "\nReplacePkg", 82 CODE_ERROR, 83 ST.ERR_UNKNOWN_FATAL_REPLACE_ERR % (Options.PackFileToReplace, Options.PackFileToBeReplaced), 84 ExtraData=ST.MSG_SEARCH_FOR_HELP % ST.MSG_EDKII_MAIL_ADDR, 85 RaiseError=False 86 ) 87 Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), 88 platform) + format_exc()) 89 90 finally: 91 Logger.Quiet(ST.MSG_REMOVE_TEMP_FILE_STARTED) 92 if DistFile: 93 DistFile.Close() 94 if ContentZipFile: 95 ContentZipFile.Close() 96 for TempDir in GlobalData.gUNPACK_DIR: 97 rmtree(TempDir) 98 GlobalData.gUNPACK_DIR = [] 99 Logger.Quiet(ST.MSG_REMOVE_TEMP_FILE_DONE) 100 101 if ReturnCode == 0: 102 Logger.Quiet(ST.MSG_FINISH) 103 104 return ReturnCode 105 106def CheckReplaceDpx(Dep, DistPkg, OrigDpGuid, OrigDpVersion): 107 NewDpPkgList = [] 108 for PkgInfo in DistPkg.PackageSurfaceArea: 109 Guid, Version = PkgInfo[0], PkgInfo[1] 110 NewDpPkgList.append((Guid, Version)) 111 112 NewDpInfo = "%s %s" % (DistPkg.Header.GetGuid(), DistPkg.Header.GetVersion()) 113 OrigDpInfo = "%s %s" % (OrigDpGuid, OrigDpVersion) 114 115 # 116 # check whether new distribution is already installed and not replacing itself 117 # 118 if (NewDpInfo != OrigDpInfo): 119 if Dep.CheckDpExists(DistPkg.Header.GetGuid(), DistPkg.Header.GetVersion()): 120 Logger.Error("\nReplacePkg", UPT_ALREADY_INSTALLED_ERROR, 121 ST.WRN_DIST_PKG_INSTALLED, 122 ExtraData=ST.MSG_REPLACE_ALREADY_INSTALLED_DP) 123 124 # 125 # check whether the original distribution could be replaced by new distribution 126 # 127 Logger.Verbose(ST.MSG_CHECK_DP_FOR_REPLACE%(NewDpInfo, OrigDpInfo)) 128 DepInfoResult = Dep.CheckDpDepexForReplace(OrigDpGuid, OrigDpVersion, NewDpPkgList) 129 Replaceable = DepInfoResult[0] 130 if not Replaceable: 131 Logger.Error("\nReplacePkg", UNKNOWN_ERROR, 132 ST.ERR_PACKAGE_NOT_MATCH_DEPENDENCY) 133 134 # 135 # check whether new distribution could be installed by dependency rule 136 # 137 Logger.Verbose(ST.MSG_CHECK_DP_FOR_INSTALL%str(NewDpInfo)) 138 if not Dep.ReplaceCheckNewDpDepex(DistPkg, OrigDpGuid, OrigDpVersion): 139 Logger.Error("\nReplacePkg", UNKNOWN_ERROR, 140 ST.ERR_PACKAGE_NOT_MATCH_DEPENDENCY, 141 ExtraData=DistPkg.Header.Name) 142 143