]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/UPT/UPT.py
BaseTools: Remove './SecMain' from 'run' target
[mirror_edk2.git] / BaseTools / Source / Python / UPT / UPT.py
1 ## @file
2 #
3 # This file is the main entry for UPT
4 #
5 # Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
6 #
7 # SPDX-License-Identifier: BSD-2-Clause-Patent
8 #
9
10 '''
11 UPT
12 '''
13
14 ## import modules
15 #
16 import locale
17 import sys
18 from imp import reload
19 encoding = locale.getdefaultlocale()[1]
20 if encoding:
21 reload(sys)
22 sys.setdefaultencoding(encoding)
23 from Core import FileHook
24 import os.path
25 from sys import platform
26 import platform as pf
27 from optparse import OptionParser
28 from traceback import format_exc
29 from platform import python_version
30
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
42 from Common.MultipleWorkspace import MultipleWorkspace as mws
43
44 import MkPkg
45 import InstallPkg
46 import RmPkg
47 import InventoryWs
48 import ReplacePkg
49 import TestInstall
50 from Library.Misc import GetWorkspace
51 from Library import GlobalData
52 from Core.IpiDb import IpiDatabase
53 from BuildVersion import gBUILD_VERSION
54
55 ## CheckConflictOption
56 #
57 # CheckConflictOption
58 #
59 def CheckConflictOption(Opt):
60 if (Opt.PackFileToCreate or Opt.PackFileToInstall or Opt.PackFileToRemove or Opt.PackFileToReplace) \
61 and Opt.InventoryWs:
62 Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_L_OA_EXCLUSIVE)
63 elif Opt.PackFileToReplace and (Opt.PackFileToCreate or Opt.PackFileToInstall or Opt.PackFileToRemove):
64 Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_U_ICR_EXCLUSIVE)
65 elif (Opt.PackFileToCreate and Opt.PackFileToInstall and Opt.PackFileToRemove):
66 Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_REQUIRE_I_C_R_OPTION)
67 elif Opt.PackFileToCreate and Opt.PackFileToInstall:
68 Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_I_C_EXCLUSIVE)
69 elif Opt.PackFileToInstall and Opt.PackFileToRemove:
70 Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_I_R_EXCLUSIVE)
71 elif Opt.PackFileToCreate and Opt.PackFileToRemove:
72 Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_C_R_EXCLUSIVE)
73 elif Opt.TestDistFiles and (Opt.PackFileToCreate or Opt.PackFileToInstall \
74 or Opt.PackFileToRemove or Opt.PackFileToReplace):
75 Logger.Error("UPT", OPTION_CONFLICT, ExtraData=ST.ERR_C_R_EXCLUSIVE)
76
77 if Opt.CustomPath and Opt.UseGuidedPkgPath:
78 Logger.Warn("UPT", ST.WARN_CUSTOMPATH_OVERRIDE_USEGUIDEDPATH)
79 Opt.UseGuidedPkgPath = False
80
81 ## SetLogLevel
82 #
83 def SetLogLevel(Opt):
84 if Opt.opt_verbose:
85 Logger.SetLevel(Logger.VERBOSE)
86 elif Opt.opt_quiet:
87 Logger.SetLevel(Logger.QUIET + 1)
88 elif Opt.debug_level is not None:
89 if Opt.debug_level < 0 or Opt.debug_level > 9:
90 Logger.Warn("UPT", ST.ERR_DEBUG_LEVEL)
91 Logger.SetLevel(Logger.INFO)
92 else:
93 Logger.SetLevel(Opt.debug_level + 1)
94 elif Opt.opt_slient:
95 Logger.SetLevel(Logger.SILENT)
96 else:
97 Logger.SetLevel(Logger.INFO)
98
99 ## Main
100 #
101 # Main
102 #
103 def Main():
104 Logger.Initialize()
105
106 Parser = OptionParser(version=(MSG_VERSION + ' Build ' + gBUILD_VERSION), description=MSG_DESCRIPTION,
107 prog="UPT.exe", usage=MSG_USAGE)
108
109 Parser.add_option("-d", "--debug", action="store", type="int", dest="debug_level", help=ST.HLP_PRINT_DEBUG_INFO)
110
111 Parser.add_option("-v", "--verbose", action="store_true", dest="opt_verbose",
112 help=ST.HLP_PRINT_INFORMATIONAL_STATEMENT)
113
114 Parser.add_option("-s", "--silent", action="store_true", dest="opt_slient", help=ST.HLP_RETURN_NO_DISPLAY)
115
116 Parser.add_option("-q", "--quiet", action="store_true", dest="opt_quiet", help=ST.HLP_RETURN_AND_DISPLAY)
117
118 Parser.add_option("-i", "--install", action="append", type="string", dest="Install_Distribution_Package_File",
119 help=ST.HLP_SPECIFY_PACKAGE_NAME_INSTALL)
120
121 Parser.add_option("-c", "--create", action="store", type="string", dest="Create_Distribution_Package_File",
122 help=ST.HLP_SPECIFY_PACKAGE_NAME_CREATE)
123
124 Parser.add_option("-r", "--remove", action="store", type="string", dest="Remove_Distribution_Package_File",
125 help=ST.HLP_SPECIFY_PACKAGE_NAME_REMOVE)
126
127 Parser.add_option("-t", "--template", action="store", type="string", dest="Package_Information_Data_File",
128 help=ST.HLP_SPECIFY_TEMPLATE_NAME_CREATE)
129
130 Parser.add_option("-p", "--dec-filename", action="append", type="string", dest="EDK2_DEC_Filename",
131 help=ST.HLP_SPECIFY_DEC_NAME_CREATE)
132
133 Parser.add_option("-m", "--inf-filename", action="append", type="string", dest="EDK2_INF_Filename",
134 help=ST.HLP_SPECIFY_INF_NAME_CREATE)
135
136 Parser.add_option("-l", "--list", action="store_true", dest="List_Dist_Installed",
137 help=ST.HLP_LIST_DIST_INSTALLED)
138
139 Parser.add_option("-f", "--force", action="store_true", dest="Yes", help=ST.HLP_DISABLE_PROMPT)
140
141 Parser.add_option("-n", "--custom-path", action="store_true", dest="CustomPath", help=ST.HLP_CUSTOM_PATH_PROMPT)
142
143 Parser.add_option("-x", "--free-lock", action="store_true", dest="SkipLock", help=ST.HLP_SKIP_LOCK_CHECK)
144
145 Parser.add_option("-u", "--replace", action="store", type="string", dest="Replace_Distribution_Package_File",
146 help=ST.HLP_SPECIFY_PACKAGE_NAME_REPLACE)
147
148 Parser.add_option("-o", "--original", action="store", type="string", dest="Original_Distribution_Package_File",
149 help=ST.HLP_SPECIFY_PACKAGE_NAME_TO_BE_REPLACED)
150
151 Parser.add_option("--use-guided-paths", action="store_true", dest="Use_Guided_Paths", help=ST.HLP_USE_GUIDED_PATHS)
152
153 Parser.add_option("-j", "--test-install", action="append", type="string",
154 dest="Test_Install_Distribution_Package_Files", help=ST.HLP_TEST_INSTALL)
155
156 Opt = Parser.parse_args()[0]
157
158 Var2Var = [
159 ("PackageInformationDataFile", Opt.Package_Information_Data_File),
160 ("PackFileToInstall", Opt.Install_Distribution_Package_File),
161 ("PackFileToCreate", Opt.Create_Distribution_Package_File),
162 ("PackFileToRemove", Opt.Remove_Distribution_Package_File),
163 ("PackageFileList", Opt.EDK2_DEC_Filename),
164 ("ModuleFileList", Opt.EDK2_INF_Filename),
165 ("InventoryWs", Opt.List_Dist_Installed),
166 ("PackFileToReplace", Opt.Replace_Distribution_Package_File),
167 ("PackFileToBeReplaced", Opt.Original_Distribution_Package_File),
168 ("UseGuidedPkgPath", Opt.Use_Guided_Paths),
169 ("TestDistFiles", Opt.Test_Install_Distribution_Package_Files)
170 ]
171
172 for Var in Var2Var:
173 setattr(Opt, Var[0], Var[1])
174
175 try:
176 GlobalData.gWORKSPACE, GlobalData.gPACKAGE_PATH = GetWorkspace()
177 except FatalError as XExcept:
178 if Logger.GetLevel() <= Logger.DEBUG_9:
179 Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), platform) + format_exc())
180 return XExcept.args[0]
181
182 # Support WORKSPACE is a long path
183 # Only works for windows system
184 if pf.system() == 'Windows':
185 Vol = 'B:'
186 for Index in range(90, 65, -1):
187 Vol = chr(Index) + ':'
188 if not os.path.isdir(Vol):
189 os.system('subst %s "%s"' % (Vol, GlobalData.gWORKSPACE))
190 break
191 GlobalData.gWORKSPACE = '%s\\' % Vol
192
193 WorkspaceDir = GlobalData.gWORKSPACE
194
195 SetLogLevel(Opt)
196
197 Mgr = FileHook.RecoverMgr(WorkspaceDir)
198 FileHook.SetRecoverMgr(Mgr)
199
200 GlobalData.gDB = IpiDatabase(os.path.normpath(os.path.join(WorkspaceDir, \
201 "Conf/DistributionPackageDatabase.db")), WorkspaceDir)
202 GlobalData.gDB.InitDatabase(Opt.SkipLock)
203
204 #
205 # Make sure the Db will get closed correctly
206 #
207 try:
208 ReturnCode = 0
209 CheckConflictOption(Opt)
210
211 RunModule = None
212 if Opt.PackFileToCreate:
213 if Opt.PackageInformationDataFile:
214 if not os.path.exists(Opt.PackageInformationDataFile):
215 if not os.path.exists(os.path.join(WorkspaceDir, Opt.PackageInformationDataFile)):
216 Logger.Error("\nUPT", FILE_NOT_FOUND, ST.ERR_NO_TEMPLATE_FILE % Opt.PackageInformationDataFile)
217 else:
218 Opt.PackageInformationDataFile = os.path.join(WorkspaceDir, Opt.PackageInformationDataFile)
219 else:
220 Logger.Error("UPT", OPTION_MISSING, ExtraData=ST.ERR_REQUIRE_T_OPTION)
221 if not Opt.PackFileToCreate.endswith('.dist'):
222 Logger.Error("CreatePkg", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_EXT_ERROR % Opt.PackFileToCreate)
223 RunModule = MkPkg.Main
224
225 elif Opt.PackFileToInstall:
226 AbsPath = []
227 for Item in Opt.PackFileToInstall:
228 if not Item.endswith('.dist'):
229 Logger.Error("InstallPkg", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_EXT_ERROR % Item)
230
231 AbsPath.append(GetFullPathDist(Item, WorkspaceDir))
232 if not AbsPath:
233 Logger.Error("InstallPkg", FILE_NOT_FOUND, ST.ERR_INSTALL_DIST_NOT_FOUND % Item)
234
235 Opt.PackFileToInstall = AbsPath
236 setattr(Opt, 'PackageFile', Opt.PackFileToInstall)
237 RunModule = InstallPkg.Main
238
239 elif Opt.PackFileToRemove:
240 if not Opt.PackFileToRemove.endswith('.dist'):
241 Logger.Error("RemovePkg", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_EXT_ERROR % Opt.PackFileToRemove)
242 head, tail = os.path.split(Opt.PackFileToRemove)
243 if head or not tail:
244 Logger.Error("RemovePkg",
245 FILE_TYPE_MISMATCH,
246 ExtraData=ST.ERR_DIST_FILENAME_ONLY_FOR_REMOVE % Opt.PackFileToRemove)
247
248 setattr(Opt, 'DistributionFile', Opt.PackFileToRemove)
249 RunModule = RmPkg.Main
250 elif Opt.InventoryWs:
251 RunModule = InventoryWs.Main
252
253 elif Opt.PackFileToBeReplaced and not Opt.PackFileToReplace:
254 Logger.Error("ReplacePkg", OPTION_MISSING, ExtraData=ST.ERR_REQUIRE_U_OPTION)
255
256 elif Opt.PackFileToReplace:
257 if not Opt.PackFileToReplace.endswith('.dist'):
258 Logger.Error("ReplacePkg", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_EXT_ERROR % Opt.PackFileToReplace)
259 if not Opt.PackFileToBeReplaced:
260 Logger.Error("ReplacePkg", OPTION_MISSING, ExtraData=ST.ERR_REQUIRE_O_OPTION)
261 if not Opt.PackFileToBeReplaced.endswith('.dist'):
262 Logger.Error("ReplacePkg",
263 FILE_TYPE_MISMATCH,
264 ExtraData=ST.ERR_DIST_EXT_ERROR % Opt.PackFileToBeReplaced)
265
266 head, tail = os.path.split(Opt.PackFileToBeReplaced)
267 if head or not tail:
268 Logger.Error("ReplacePkg",
269 FILE_TYPE_MISMATCH,
270 ExtraData=ST.ERR_DIST_FILENAME_ONLY_FOR_REPLACE_ORIG % Opt.PackFileToBeReplaced)
271
272 AbsPath = GetFullPathDist(Opt.PackFileToReplace, WorkspaceDir)
273 if not AbsPath:
274 Logger.Error("ReplacePkg", FILE_NOT_FOUND, ST.ERR_REPLACE_DIST_NOT_FOUND % Opt.PackFileToReplace)
275
276 Opt.PackFileToReplace = AbsPath
277 RunModule = ReplacePkg.Main
278
279 elif Opt.Test_Install_Distribution_Package_Files:
280 for Dist in Opt.Test_Install_Distribution_Package_Files:
281 if not Dist.endswith('.dist'):
282 Logger.Error("TestInstall", FILE_TYPE_MISMATCH, ExtraData=ST.ERR_DIST_EXT_ERROR % Dist)
283
284 setattr(Opt, 'DistFiles', Opt.Test_Install_Distribution_Package_Files)
285 RunModule = TestInstall.Main
286
287 else:
288 Parser.print_usage()
289 return OPTION_MISSING
290
291 ReturnCode = RunModule(Opt)
292 except FatalError as XExcept:
293 ReturnCode = XExcept.args[0]
294 if Logger.GetLevel() <= Logger.DEBUG_9:
295 Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), platform) + \
296 format_exc())
297 finally:
298 try:
299 if ReturnCode != 0 and ReturnCode != UPT_ALREADY_INSTALLED_ERROR:
300 Logger.Quiet(ST.MSG_RECOVER_START)
301 GlobalData.gDB.RollBack()
302 Mgr.rollback()
303 Logger.Quiet(ST.MSG_RECOVER_DONE)
304 else:
305 GlobalData.gDB.Commit()
306 Mgr.commit()
307 except Exception:
308 Logger.Quiet(ST.MSG_RECOVER_FAIL)
309 GlobalData.gDB.CloseDb()
310
311 if pf.system() == 'Windows':
312 os.system('subst %s /D' % GlobalData.gWORKSPACE.replace('\\', ''))
313
314 return ReturnCode
315
316 ## GetFullPathDist
317 #
318 # This function will check DistFile existence, if not absolute path, then try current working directory,
319 # then $(WORKSPACE),and return the AbsPath. If file doesn't find, then return None
320 #
321 # @param DistFile: The distribution file in either relative path or absolute path
322 # @param WorkspaceDir: Workspace Directory
323 # @return AbsPath: The Absolute path of the distribution file if existed, None else
324 #
325 def GetFullPathDist(DistFile, WorkspaceDir):
326 if os.path.isabs(DistFile):
327 if not (os.path.exists(DistFile) and os.path.isfile(DistFile)):
328 return None
329 else:
330 return DistFile
331 else:
332 AbsPath = os.path.normpath(os.path.join(os.getcwd(), DistFile))
333 if not (os.path.exists(AbsPath) and os.path.isfile(AbsPath)):
334 AbsPath = os.path.normpath(os.path.join(WorkspaceDir, DistFile))
335 if not (os.path.exists(AbsPath) and os.path.isfile(AbsPath)):
336 return None
337
338 return AbsPath
339
340 if __name__ == '__main__':
341 RETVAL = Main()
342 #
343 # 0-127 is a safe return range, and 1 is a standard default error
344 #
345 if RETVAL < 0 or RETVAL > 127:
346 RETVAL = 1
347 sys.exit(RETVAL)