3 # This file is the main entry for UPT
5 # Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>
7 # This program and the accompanying materials are licensed and made available
8 # under the terms and conditions of the BSD License which accompanies this
9 # distribution. The full text of the license may be found at
10 # http://opensource.org/licenses/bsd-license.php
12 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
22 from Core
import FileHook
25 from sys
import platform
27 from optparse
import OptionParser
28 from traceback
import format_exc
29 from platform
import python_version
31 from Logger
import StringTable
as ST
32 import Logger
.Log
as Logger
33 from Logger
.StringTable
import MSG_VERSION
34 from Logger
.StringTable
import MSG_DESCRIPTION
35 from Logger
.StringTable
import MSG_USAGE
36 from Logger
.ToolError
import FILE_NOT_FOUND
37 from Logger
.ToolError
import OPTION_MISSING
38 from Logger
.ToolError
import FILE_TYPE_MISMATCH
39 from Logger
.ToolError
import OPTION_CONFLICT
40 from Logger
.ToolError
import FatalError
41 from Logger
.ToolError
import UPT_ALREADY_INSTALLED_ERROR
48 from Library
.Misc
import GetWorkspace
49 from Library
import GlobalData
50 from Core
.IpiDb
import IpiDatabase
51 from BuildVersion
import gBUILD_VERSION
53 ## CheckConflictOption
57 def CheckConflictOption(Opt
):
58 if (Opt
.PackFileToCreate
or Opt
.PackFileToInstall
or Opt
.PackFileToRemove
or Opt
.PackFileToReplace
) \
60 Logger
.Error("UPT", OPTION_CONFLICT
, ExtraData
=ST
.ERR_L_OA_EXCLUSIVE
)
61 elif Opt
.PackFileToReplace
and (Opt
.PackFileToCreate
or Opt
.PackFileToInstall
or Opt
.PackFileToRemove
):
62 Logger
.Error("UPT", OPTION_CONFLICT
, ExtraData
=ST
.ERR_U_ICR_EXCLUSIVE
)
63 elif (Opt
.PackFileToCreate
and Opt
.PackFileToInstall
and Opt
.PackFileToRemove
):
64 Logger
.Error("UPT", OPTION_CONFLICT
, ExtraData
=ST
.ERR_REQUIRE_I_C_R_OPTION
)
65 elif Opt
.PackFileToCreate
and Opt
.PackFileToInstall
:
66 Logger
.Error("UPT", OPTION_CONFLICT
, ExtraData
=ST
.ERR_I_C_EXCLUSIVE
)
67 elif Opt
.PackFileToInstall
and Opt
.PackFileToRemove
:
68 Logger
.Error("UPT", OPTION_CONFLICT
, ExtraData
=ST
.ERR_I_R_EXCLUSIVE
)
69 elif Opt
.PackFileToCreate
and Opt
.PackFileToRemove
:
70 Logger
.Error("UPT", OPTION_CONFLICT
, ExtraData
=ST
.ERR_C_R_EXCLUSIVE
)
72 if Opt
.CustomPath
and Opt
.UseGuidedPkgPath
:
73 Logger
.Warn("UPT", ST
.WARN_CUSTOMPATH_OVERRIDE_USEGUIDEDPATH
)
74 Opt
.UseGuidedPkgPath
= False
80 Logger
.SetLevel(Logger
.VERBOSE
)
82 Logger
.SetLevel(Logger
.QUIET
+ 1)
83 elif Opt
.debug_level
!= None:
84 if Opt
.debug_level
< 0 or Opt
.debug_level
> 9:
85 Logger
.Warn("UPT", ST
.ERR_DEBUG_LEVEL
)
86 Logger
.SetLevel(Logger
.INFO
)
88 Logger
.SetLevel(Opt
.debug_level
+ 1)
90 Logger
.SetLevel(Logger
.SILENT
)
92 Logger
.SetLevel(Logger
.INFO
)
101 Parser
= OptionParser(version
=(MSG_VERSION
+ ' ' + gBUILD_VERSION
), description
=MSG_DESCRIPTION
,
102 prog
="UPT.exe", usage
=MSG_USAGE
)
104 Parser
.add_option("-d", "--debug", action
="store", type="int", dest
="debug_level", help=ST
.HLP_PRINT_DEBUG_INFO
)
106 Parser
.add_option("-v", "--verbose", action
="store_true", dest
="opt_verbose",
107 help=ST
.HLP_PRINT_INFORMATIONAL_STATEMENT
)
109 Parser
.add_option("-s", "--silent", action
="store_true", dest
="opt_slient", help=ST
.HLP_RETURN_NO_DISPLAY
)
111 Parser
.add_option("-q", "--quiet", action
="store_true", dest
="opt_quiet", help=ST
.HLP_RETURN_AND_DISPLAY
)
113 Parser
.add_option("-i", "--install", action
="store", type="string", dest
="Install_Distribution_Package_File",
114 help=ST
.HLP_SPECIFY_PACKAGE_NAME_INSTALL
)
116 Parser
.add_option("-c", "--create", action
="store", type="string", dest
="Create_Distribution_Package_File",
117 help=ST
.HLP_SPECIFY_PACKAGE_NAME_CREATE
)
119 Parser
.add_option("-r", "--remove", action
="store", type="string", dest
="Remove_Distribution_Package_File",
120 help=ST
.HLP_SPECIFY_PACKAGE_NAME_REMOVE
)
122 Parser
.add_option("-t", "--template", action
="store", type="string", dest
="Package_Information_Data_File",
123 help=ST
.HLP_SPECIFY_TEMPLATE_NAME_CREATE
)
125 Parser
.add_option("-p", "--dec-filename", action
="append", type="string", dest
="EDK2_DEC_Filename",
126 help=ST
.HLP_SPECIFY_DEC_NAME_CREATE
)
128 Parser
.add_option("-m", "--inf-filename", action
="append", type="string", dest
="EDK2_INF_Filename",
129 help=ST
.HLP_SPECIFY_INF_NAME_CREATE
)
131 Parser
.add_option("-l", "--list", action
="store_true", dest
="List_Dist_Installed",
132 help=ST
.HLP_LIST_DIST_INSTALLED
)
134 Parser
.add_option("-f", "--force", action
="store_true", dest
="Yes", help=ST
.HLP_DISABLE_PROMPT
)
136 Parser
.add_option("-n", "--custom-path", action
="store_true", dest
="CustomPath", help=ST
.HLP_CUSTOM_PATH_PROMPT
)
138 Parser
.add_option("-x", "--free-lock", action
="store_true", dest
="SkipLock", help=ST
.HLP_SKIP_LOCK_CHECK
)
140 Parser
.add_option("-u", "--replace", action
="store", type="string", dest
="Replace_Distribution_Package_File",
141 help=ST
.HLP_SPECIFY_PACKAGE_NAME_REPLACE
)
143 Parser
.add_option("-o", "--original", action
="store", type="string", dest
="Original_Distribution_Package_File",
144 help=ST
.HLP_SPECIFY_PACKAGE_NAME_TO_BE_REPLACED
)
146 Parser
.add_option("--use-guided-paths", action
="store_true", dest
="Use_Guided_Paths", help=ST
.HLP_USE_GUIDED_PATHS
)
148 Opt
= Parser
.parse_args()[0]
151 ("PackageInformationDataFile", Opt
.Package_Information_Data_File
),
152 ("PackFileToInstall", Opt
.Install_Distribution_Package_File
),
153 ("PackFileToCreate", Opt
.Create_Distribution_Package_File
),
154 ("PackFileToRemove", Opt
.Remove_Distribution_Package_File
),
155 ("PackageFileList", Opt
.EDK2_DEC_Filename
),
156 ("ModuleFileList", Opt
.EDK2_INF_Filename
),
157 ("InventoryWs", Opt
.List_Dist_Installed
),
158 ("PackFileToReplace", Opt
.Replace_Distribution_Package_File
),
159 ("PackFileToBeReplaced", Opt
.Original_Distribution_Package_File
),
160 ("UseGuidedPkgPath", Opt
.Use_Guided_Paths
),
164 setattr(Opt
, Var
[0], Var
[1])
167 GlobalData
.gWORKSPACE
= GetWorkspace()
168 except FatalError
, XExcept
:
169 if Logger
.GetLevel() <= Logger
.DEBUG_9
:
170 Logger
.Quiet(ST
.MSG_PYTHON_ON
% (python_version(), platform
) + format_exc())
171 return XExcept
.args
[0]
173 # Start *********************************************
174 # Support WORKSPACE is a long path
175 # Only work well on windows
177 if pf
.system() == 'Windows':
178 os
.system('@echo off\nsubst b: /D')
179 os
.system('subst b: "%s"' % GlobalData
.gWORKSPACE
)
180 GlobalData
.gWORKSPACE
= 'B:\\'
181 # End ***********************************************
183 WorkspaceDir
= GlobalData
.gWORKSPACE
187 Mgr
= FileHook
.RecoverMgr(WorkspaceDir
)
188 FileHook
.SetRecoverMgr(Mgr
)
190 GlobalData
.gDB
= IpiDatabase(os
.path
.normpath(os
.path
.join(WorkspaceDir
, \
191 "Conf/DistributionPackageDatabase.db")), WorkspaceDir
)
192 GlobalData
.gDB
.InitDatabase(Opt
.SkipLock
)
195 # Make sure the Db will get closed correctly
199 CheckConflictOption(Opt
)
202 if Opt
.PackFileToCreate
:
203 if Opt
.PackageInformationDataFile
:
204 if not os
.path
.exists(Opt
.PackageInformationDataFile
):
205 if not os
.path
.exists(os
.path
.join(WorkspaceDir
, Opt
.PackageInformationDataFile
)):
206 Logger
.Error("\nUPT", FILE_NOT_FOUND
, ST
.ERR_NO_TEMPLATE_FILE
% Opt
.PackageInformationDataFile
)
208 Opt
.PackageInformationDataFile
= os
.path
.join(WorkspaceDir
, Opt
.PackageInformationDataFile
)
210 Logger
.Error("UPT", OPTION_MISSING
, ExtraData
=ST
.ERR_REQUIRE_T_OPTION
)
211 if not Opt
.PackFileToCreate
.endswith('.dist'):
212 Logger
.Error("CreatePkg", FILE_TYPE_MISMATCH
, ExtraData
=ST
.ERR_DIST_EXT_ERROR
% Opt
.PackFileToCreate
)
213 RunModule
= MkPkg
.Main
215 elif Opt
.PackFileToInstall
:
216 if not Opt
.PackFileToInstall
.endswith('.dist'):
217 Logger
.Error("InstallPkg", FILE_TYPE_MISMATCH
, ExtraData
=ST
.ERR_DIST_EXT_ERROR
% Opt
.PackFileToInstall
)
219 AbsPath
= GetFullPathDist(Opt
.PackFileToInstall
, WorkspaceDir
)
221 Logger
.Error("InstallPkg", FILE_NOT_FOUND
, ST
.ERR_INSTALL_DIST_NOT_FOUND
% Opt
.PackFileToInstall
)
223 Opt
.PackFileToInstall
= AbsPath
224 setattr(Opt
, 'PackageFile', Opt
.PackFileToInstall
)
225 RunModule
= InstallPkg
.Main
227 elif Opt
.PackFileToRemove
:
228 if not Opt
.PackFileToRemove
.endswith('.dist'):
229 Logger
.Error("RemovePkg", FILE_TYPE_MISMATCH
, ExtraData
=ST
.ERR_DIST_EXT_ERROR
% Opt
.PackFileToRemove
)
230 head
, tail
= os
.path
.split(Opt
.PackFileToRemove
)
232 Logger
.Error("RemovePkg",
234 ExtraData
=ST
.ERR_DIST_FILENAME_ONLY_FOR_REMOVE
% Opt
.PackFileToRemove
)
236 setattr(Opt
, 'DistributionFile', Opt
.PackFileToRemove
)
237 RunModule
= RmPkg
.Main
238 elif Opt
.InventoryWs
:
239 RunModule
= InventoryWs
.Main
241 elif Opt
.PackFileToBeReplaced
and not Opt
.PackFileToReplace
:
242 Logger
.Error("ReplacePkg", OPTION_MISSING
, ExtraData
=ST
.ERR_REQUIRE_U_OPTION
)
244 elif Opt
.PackFileToReplace
:
245 if not Opt
.PackFileToReplace
.endswith('.dist'):
246 Logger
.Error("ReplacePkg", FILE_TYPE_MISMATCH
, ExtraData
=ST
.ERR_DIST_EXT_ERROR
% Opt
.PackFileToReplace
)
247 if not Opt
.PackFileToBeReplaced
:
248 Logger
.Error("ReplacePkg", OPTION_MISSING
, ExtraData
=ST
.ERR_REQUIRE_O_OPTION
)
249 if not Opt
.PackFileToBeReplaced
.endswith('.dist'):
250 Logger
.Error("ReplacePkg",
252 ExtraData
=ST
.ERR_DIST_EXT_ERROR
% Opt
.PackFileToBeReplaced
)
254 head
, tail
= os
.path
.split(Opt
.PackFileToBeReplaced
)
256 Logger
.Error("ReplacePkg",
258 ExtraData
=ST
.ERR_DIST_FILENAME_ONLY_FOR_REPLACE_ORIG
% Opt
.PackFileToBeReplaced
)
260 AbsPath
= GetFullPathDist(Opt
.PackFileToReplace
, WorkspaceDir
)
262 Logger
.Error("ReplacePkg", FILE_NOT_FOUND
, ST
.ERR_REPLACE_DIST_NOT_FOUND
% Opt
.PackFileToReplace
)
264 Opt
.PackFileToReplace
= AbsPath
265 RunModule
= ReplacePkg
.Main
269 return OPTION_MISSING
271 ReturnCode
= RunModule(Opt
)
272 except FatalError
, XExcept
:
273 ReturnCode
= XExcept
.args
[0]
274 if Logger
.GetLevel() <= Logger
.DEBUG_9
:
275 Logger
.Quiet(ST
.MSG_PYTHON_ON
% (python_version(), platform
) + \
279 if ReturnCode
!= 0 and ReturnCode
!= UPT_ALREADY_INSTALLED_ERROR
:
280 Logger
.Quiet(ST
.MSG_RECOVER_START
)
281 GlobalData
.gDB
.RollBack()
283 Logger
.Quiet(ST
.MSG_RECOVER_DONE
)
285 GlobalData
.gDB
.Commit()
287 except StandardError:
288 Logger
.Quiet(ST
.MSG_RECOVER_FAIL
)
289 GlobalData
.gDB
.CloseDb()
290 if pf
.system() == 'Windows':
291 os
.system('subst b: /D')
297 # This function will check DistFile existence, if not absolute path, then try current working directory,
298 # then $(WORKSPACE),and return the AbsPath. If file doesn't find, then return None
300 # @param DistFile: The distribution file in either relative path or absolute path
301 # @param WorkspaceDir: Workspace Directory
302 # @return AbsPath: The Absolute path of the distribution file if existed, None else
304 def GetFullPathDist(DistFile
, WorkspaceDir
):
305 if os
.path
.isabs(DistFile
):
306 if not (os
.path
.exists(DistFile
) and os
.path
.isfile(DistFile
)):
311 AbsPath
= os
.path
.normpath(os
.path
.join(os
.getcwd(), DistFile
))
312 if not (os
.path
.exists(AbsPath
) and os
.path
.isfile(AbsPath
)):
313 AbsPath
= os
.path
.normpath(os
.path
.join(WorkspaceDir
, DistFile
))
314 if not (os
.path
.exists(AbsPath
) and os
.path
.isfile(AbsPath
)):
319 if __name__
== '__main__':
322 # 0-127 is a safe return range, and 1 is a standard default error
324 if RETVAL
< 0 or RETVAL
> 127: