3 # This file is the main entry for UPT
5 # Copyright (c) 2011 - 2016, 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
42 from Common
.MultipleWorkspace
import MultipleWorkspace
as mws
50 from Library
.Misc
import GetWorkspace
51 from Library
import GlobalData
52 from Core
.IpiDb
import IpiDatabase
53 from BuildVersion
import gBUILD_VERSION
55 ## CheckConflictOption
59 def CheckConflictOption(Opt
):
60 if (Opt
.PackFileToCreate
or Opt
.PackFileToInstall
or Opt
.PackFileToRemove
or Opt
.PackFileToReplace
) \
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
)
77 if Opt
.CustomPath
and Opt
.UseGuidedPkgPath
:
78 Logger
.Warn("UPT", ST
.WARN_CUSTOMPATH_OVERRIDE_USEGUIDEDPATH
)
79 Opt
.UseGuidedPkgPath
= False
85 Logger
.SetLevel(Logger
.VERBOSE
)
87 Logger
.SetLevel(Logger
.QUIET
+ 1)
88 elif Opt
.debug_level
!= 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
)
93 Logger
.SetLevel(Opt
.debug_level
+ 1)
95 Logger
.SetLevel(Logger
.SILENT
)
97 Logger
.SetLevel(Logger
.INFO
)
106 Parser
= OptionParser(version
=(MSG_VERSION
+ ' Build ' + gBUILD_VERSION
), description
=MSG_DESCRIPTION
,
107 prog
="UPT.exe", usage
=MSG_USAGE
)
109 Parser
.add_option("-d", "--debug", action
="store", type="int", dest
="debug_level", help=ST
.HLP_PRINT_DEBUG_INFO
)
111 Parser
.add_option("-v", "--verbose", action
="store_true", dest
="opt_verbose",
112 help=ST
.HLP_PRINT_INFORMATIONAL_STATEMENT
)
114 Parser
.add_option("-s", "--silent", action
="store_true", dest
="opt_slient", help=ST
.HLP_RETURN_NO_DISPLAY
)
116 Parser
.add_option("-q", "--quiet", action
="store_true", dest
="opt_quiet", help=ST
.HLP_RETURN_AND_DISPLAY
)
118 Parser
.add_option("-i", "--install", action
="store", type="string", dest
="Install_Distribution_Package_File",
119 help=ST
.HLP_SPECIFY_PACKAGE_NAME_INSTALL
)
121 Parser
.add_option("-c", "--create", action
="store", type="string", dest
="Create_Distribution_Package_File",
122 help=ST
.HLP_SPECIFY_PACKAGE_NAME_CREATE
)
124 Parser
.add_option("-r", "--remove", action
="store", type="string", dest
="Remove_Distribution_Package_File",
125 help=ST
.HLP_SPECIFY_PACKAGE_NAME_REMOVE
)
127 Parser
.add_option("-t", "--template", action
="store", type="string", dest
="Package_Information_Data_File",
128 help=ST
.HLP_SPECIFY_TEMPLATE_NAME_CREATE
)
130 Parser
.add_option("-p", "--dec-filename", action
="append", type="string", dest
="EDK2_DEC_Filename",
131 help=ST
.HLP_SPECIFY_DEC_NAME_CREATE
)
133 Parser
.add_option("-m", "--inf-filename", action
="append", type="string", dest
="EDK2_INF_Filename",
134 help=ST
.HLP_SPECIFY_INF_NAME_CREATE
)
136 Parser
.add_option("-l", "--list", action
="store_true", dest
="List_Dist_Installed",
137 help=ST
.HLP_LIST_DIST_INSTALLED
)
139 Parser
.add_option("-f", "--force", action
="store_true", dest
="Yes", help=ST
.HLP_DISABLE_PROMPT
)
141 Parser
.add_option("-n", "--custom-path", action
="store_true", dest
="CustomPath", help=ST
.HLP_CUSTOM_PATH_PROMPT
)
143 Parser
.add_option("-x", "--free-lock", action
="store_true", dest
="SkipLock", help=ST
.HLP_SKIP_LOCK_CHECK
)
145 Parser
.add_option("-u", "--replace", action
="store", type="string", dest
="Replace_Distribution_Package_File",
146 help=ST
.HLP_SPECIFY_PACKAGE_NAME_REPLACE
)
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
)
151 Parser
.add_option("--use-guided-paths", action
="store_true", dest
="Use_Guided_Paths", help=ST
.HLP_USE_GUIDED_PATHS
)
153 Parser
.add_option("-j", "--test-install", action
="append", type="string",
154 dest
="Test_Install_Distribution_Package_Files", help=ST
.HLP_TEST_INSTALL
)
156 Opt
= Parser
.parse_args()[0]
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
)
173 setattr(Opt
, Var
[0], Var
[1])
176 GlobalData
.gWORKSPACE
, GlobalData
.gPACKAGE_PATH
= GetWorkspace()
177 except FatalError
, 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]
182 # Start *********************************************
183 # Support WORKSPACE is a long path
184 # Only work well on windows
186 if pf
.system() == 'Windows':
187 os
.system('@echo off\nsubst b: /D')
188 os
.system('subst b: "%s"' % GlobalData
.gWORKSPACE
)
189 GlobalData
.gWORKSPACE
= 'B:\\'
190 # End ***********************************************
192 WorkspaceDir
= GlobalData
.gWORKSPACE
196 Mgr
= FileHook
.RecoverMgr(WorkspaceDir
)
197 FileHook
.SetRecoverMgr(Mgr
)
199 GlobalData
.gDB
= IpiDatabase(os
.path
.normpath(os
.path
.join(WorkspaceDir
, \
200 "Conf/DistributionPackageDatabase.db")), WorkspaceDir
)
201 GlobalData
.gDB
.InitDatabase(Opt
.SkipLock
)
204 # Make sure the Db will get closed correctly
208 CheckConflictOption(Opt
)
211 if Opt
.PackFileToCreate
:
212 if Opt
.PackageInformationDataFile
:
213 if not os
.path
.exists(Opt
.PackageInformationDataFile
):
214 if not os
.path
.exists(os
.path
.join(WorkspaceDir
, Opt
.PackageInformationDataFile
)):
215 Logger
.Error("\nUPT", FILE_NOT_FOUND
, ST
.ERR_NO_TEMPLATE_FILE
% Opt
.PackageInformationDataFile
)
217 Opt
.PackageInformationDataFile
= os
.path
.join(WorkspaceDir
, Opt
.PackageInformationDataFile
)
219 Logger
.Error("UPT", OPTION_MISSING
, ExtraData
=ST
.ERR_REQUIRE_T_OPTION
)
220 if not Opt
.PackFileToCreate
.endswith('.dist'):
221 Logger
.Error("CreatePkg", FILE_TYPE_MISMATCH
, ExtraData
=ST
.ERR_DIST_EXT_ERROR
% Opt
.PackFileToCreate
)
222 RunModule
= MkPkg
.Main
224 elif Opt
.PackFileToInstall
:
225 if not Opt
.PackFileToInstall
.endswith('.dist'):
226 Logger
.Error("InstallPkg", FILE_TYPE_MISMATCH
, ExtraData
=ST
.ERR_DIST_EXT_ERROR
% Opt
.PackFileToInstall
)
228 AbsPath
= GetFullPathDist(Opt
.PackFileToInstall
, WorkspaceDir
)
230 Logger
.Error("InstallPkg", FILE_NOT_FOUND
, ST
.ERR_INSTALL_DIST_NOT_FOUND
% Opt
.PackFileToInstall
)
232 Opt
.PackFileToInstall
= AbsPath
233 setattr(Opt
, 'PackageFile', Opt
.PackFileToInstall
)
234 RunModule
= InstallPkg
.Main
236 elif Opt
.PackFileToRemove
:
237 if not Opt
.PackFileToRemove
.endswith('.dist'):
238 Logger
.Error("RemovePkg", FILE_TYPE_MISMATCH
, ExtraData
=ST
.ERR_DIST_EXT_ERROR
% Opt
.PackFileToRemove
)
239 head
, tail
= os
.path
.split(Opt
.PackFileToRemove
)
241 Logger
.Error("RemovePkg",
243 ExtraData
=ST
.ERR_DIST_FILENAME_ONLY_FOR_REMOVE
% Opt
.PackFileToRemove
)
245 setattr(Opt
, 'DistributionFile', Opt
.PackFileToRemove
)
246 RunModule
= RmPkg
.Main
247 elif Opt
.InventoryWs
:
248 RunModule
= InventoryWs
.Main
250 elif Opt
.PackFileToBeReplaced
and not Opt
.PackFileToReplace
:
251 Logger
.Error("ReplacePkg", OPTION_MISSING
, ExtraData
=ST
.ERR_REQUIRE_U_OPTION
)
253 elif Opt
.PackFileToReplace
:
254 if not Opt
.PackFileToReplace
.endswith('.dist'):
255 Logger
.Error("ReplacePkg", FILE_TYPE_MISMATCH
, ExtraData
=ST
.ERR_DIST_EXT_ERROR
% Opt
.PackFileToReplace
)
256 if not Opt
.PackFileToBeReplaced
:
257 Logger
.Error("ReplacePkg", OPTION_MISSING
, ExtraData
=ST
.ERR_REQUIRE_O_OPTION
)
258 if not Opt
.PackFileToBeReplaced
.endswith('.dist'):
259 Logger
.Error("ReplacePkg",
261 ExtraData
=ST
.ERR_DIST_EXT_ERROR
% Opt
.PackFileToBeReplaced
)
263 head
, tail
= os
.path
.split(Opt
.PackFileToBeReplaced
)
265 Logger
.Error("ReplacePkg",
267 ExtraData
=ST
.ERR_DIST_FILENAME_ONLY_FOR_REPLACE_ORIG
% Opt
.PackFileToBeReplaced
)
269 AbsPath
= GetFullPathDist(Opt
.PackFileToReplace
, WorkspaceDir
)
271 Logger
.Error("ReplacePkg", FILE_NOT_FOUND
, ST
.ERR_REPLACE_DIST_NOT_FOUND
% Opt
.PackFileToReplace
)
273 Opt
.PackFileToReplace
= AbsPath
274 RunModule
= ReplacePkg
.Main
276 elif Opt
.Test_Install_Distribution_Package_Files
:
277 for Dist
in Opt
.Test_Install_Distribution_Package_Files
:
278 if not Dist
.endswith('.dist'):
279 Logger
.Error("TestInstall", FILE_TYPE_MISMATCH
, ExtraData
=ST
.ERR_DIST_EXT_ERROR
% Dist
)
281 setattr(Opt
, 'DistFiles', Opt
.Test_Install_Distribution_Package_Files
)
282 RunModule
= TestInstall
.Main
286 return OPTION_MISSING
288 ReturnCode
= RunModule(Opt
)
289 except FatalError
, XExcept
:
290 ReturnCode
= XExcept
.args
[0]
291 if Logger
.GetLevel() <= Logger
.DEBUG_9
:
292 Logger
.Quiet(ST
.MSG_PYTHON_ON
% (python_version(), platform
) + \
296 if ReturnCode
!= 0 and ReturnCode
!= UPT_ALREADY_INSTALLED_ERROR
:
297 Logger
.Quiet(ST
.MSG_RECOVER_START
)
298 GlobalData
.gDB
.RollBack()
300 Logger
.Quiet(ST
.MSG_RECOVER_DONE
)
302 GlobalData
.gDB
.Commit()
304 except StandardError:
305 Logger
.Quiet(ST
.MSG_RECOVER_FAIL
)
306 GlobalData
.gDB
.CloseDb()
307 if pf
.system() == 'Windows':
308 os
.system('subst b: /D')
314 # This function will check DistFile existence, if not absolute path, then try current working directory,
315 # then $(WORKSPACE),and return the AbsPath. If file doesn't find, then return None
317 # @param DistFile: The distribution file in either relative path or absolute path
318 # @param WorkspaceDir: Workspace Directory
319 # @return AbsPath: The Absolute path of the distribution file if existed, None else
321 def GetFullPathDist(DistFile
, WorkspaceDir
):
322 if os
.path
.isabs(DistFile
):
323 if not (os
.path
.exists(DistFile
) and os
.path
.isfile(DistFile
)):
328 AbsPath
= os
.path
.normpath(os
.path
.join(os
.getcwd(), DistFile
))
329 if not (os
.path
.exists(AbsPath
) and os
.path
.isfile(AbsPath
)):
330 AbsPath
= os
.path
.normpath(os
.path
.join(WorkspaceDir
, DistFile
))
331 if not (os
.path
.exists(AbsPath
) and os
.path
.isfile(AbsPath
)):
336 if __name__
== '__main__':
339 # 0-127 is a safe return range, and 1 is a standard default error
341 if RETVAL
< 0 or RETVAL
> 127: