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