3 # This file is the main entry for UPT
5 # Copyright (c) 2011 - 2017, 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 # Support WORKSPACE is a long path
183 # Only works for windows system
184 if pf
.system() == 'Windows':
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
))
191 GlobalData
.gWORKSPACE
= '%s\\' % Vol
193 WorkspaceDir
= GlobalData
.gWORKSPACE
197 Mgr
= FileHook
.RecoverMgr(WorkspaceDir
)
198 FileHook
.SetRecoverMgr(Mgr
)
200 GlobalData
.gDB
= IpiDatabase(os
.path
.normpath(os
.path
.join(WorkspaceDir
, \
201 "Conf/DistributionPackageDatabase.db")), WorkspaceDir
)
202 GlobalData
.gDB
.InitDatabase(Opt
.SkipLock
)
205 # Make sure the Db will get closed correctly
209 CheckConflictOption(Opt
)
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
)
218 Opt
.PackageInformationDataFile
= os
.path
.join(WorkspaceDir
, Opt
.PackageInformationDataFile
)
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
225 elif Opt
.PackFileToInstall
:
226 if not Opt
.PackFileToInstall
.endswith('.dist'):
227 Logger
.Error("InstallPkg", FILE_TYPE_MISMATCH
, ExtraData
=ST
.ERR_DIST_EXT_ERROR
% Opt
.PackFileToInstall
)
229 AbsPath
= GetFullPathDist(Opt
.PackFileToInstall
, WorkspaceDir
)
231 Logger
.Error("InstallPkg", FILE_NOT_FOUND
, ST
.ERR_INSTALL_DIST_NOT_FOUND
% Opt
.PackFileToInstall
)
233 Opt
.PackFileToInstall
= AbsPath
234 setattr(Opt
, 'PackageFile', Opt
.PackFileToInstall
)
235 RunModule
= InstallPkg
.Main
237 elif Opt
.PackFileToRemove
:
238 if not Opt
.PackFileToRemove
.endswith('.dist'):
239 Logger
.Error("RemovePkg", FILE_TYPE_MISMATCH
, ExtraData
=ST
.ERR_DIST_EXT_ERROR
% Opt
.PackFileToRemove
)
240 head
, tail
= os
.path
.split(Opt
.PackFileToRemove
)
242 Logger
.Error("RemovePkg",
244 ExtraData
=ST
.ERR_DIST_FILENAME_ONLY_FOR_REMOVE
% Opt
.PackFileToRemove
)
246 setattr(Opt
, 'DistributionFile', Opt
.PackFileToRemove
)
247 RunModule
= RmPkg
.Main
248 elif Opt
.InventoryWs
:
249 RunModule
= InventoryWs
.Main
251 elif Opt
.PackFileToBeReplaced
and not Opt
.PackFileToReplace
:
252 Logger
.Error("ReplacePkg", OPTION_MISSING
, ExtraData
=ST
.ERR_REQUIRE_U_OPTION
)
254 elif Opt
.PackFileToReplace
:
255 if not Opt
.PackFileToReplace
.endswith('.dist'):
256 Logger
.Error("ReplacePkg", FILE_TYPE_MISMATCH
, ExtraData
=ST
.ERR_DIST_EXT_ERROR
% Opt
.PackFileToReplace
)
257 if not Opt
.PackFileToBeReplaced
:
258 Logger
.Error("ReplacePkg", OPTION_MISSING
, ExtraData
=ST
.ERR_REQUIRE_O_OPTION
)
259 if not Opt
.PackFileToBeReplaced
.endswith('.dist'):
260 Logger
.Error("ReplacePkg",
262 ExtraData
=ST
.ERR_DIST_EXT_ERROR
% Opt
.PackFileToBeReplaced
)
264 head
, tail
= os
.path
.split(Opt
.PackFileToBeReplaced
)
266 Logger
.Error("ReplacePkg",
268 ExtraData
=ST
.ERR_DIST_FILENAME_ONLY_FOR_REPLACE_ORIG
% Opt
.PackFileToBeReplaced
)
270 AbsPath
= GetFullPathDist(Opt
.PackFileToReplace
, WorkspaceDir
)
272 Logger
.Error("ReplacePkg", FILE_NOT_FOUND
, ST
.ERR_REPLACE_DIST_NOT_FOUND
% Opt
.PackFileToReplace
)
274 Opt
.PackFileToReplace
= AbsPath
275 RunModule
= ReplacePkg
.Main
277 elif Opt
.Test_Install_Distribution_Package_Files
:
278 for Dist
in Opt
.Test_Install_Distribution_Package_Files
:
279 if not Dist
.endswith('.dist'):
280 Logger
.Error("TestInstall", FILE_TYPE_MISMATCH
, ExtraData
=ST
.ERR_DIST_EXT_ERROR
% Dist
)
282 setattr(Opt
, 'DistFiles', Opt
.Test_Install_Distribution_Package_Files
)
283 RunModule
= TestInstall
.Main
287 return OPTION_MISSING
289 ReturnCode
= RunModule(Opt
)
290 except FatalError
, XExcept
:
291 ReturnCode
= XExcept
.args
[0]
292 if Logger
.GetLevel() <= Logger
.DEBUG_9
:
293 Logger
.Quiet(ST
.MSG_PYTHON_ON
% (python_version(), platform
) + \
297 if ReturnCode
!= 0 and ReturnCode
!= UPT_ALREADY_INSTALLED_ERROR
:
298 Logger
.Quiet(ST
.MSG_RECOVER_START
)
299 GlobalData
.gDB
.RollBack()
301 Logger
.Quiet(ST
.MSG_RECOVER_DONE
)
303 GlobalData
.gDB
.Commit()
305 except StandardError:
306 Logger
.Quiet(ST
.MSG_RECOVER_FAIL
)
307 GlobalData
.gDB
.CloseDb()
309 if pf
.system() == 'Windows':
310 os
.system('subst %s /D' % GlobalData
.gWORKSPACE
.replace('\\',''))
316 # This function will check DistFile existence, if not absolute path, then try current working directory,
317 # then $(WORKSPACE),and return the AbsPath. If file doesn't find, then return None
319 # @param DistFile: The distribution file in either relative path or absolute path
320 # @param WorkspaceDir: Workspace Directory
321 # @return AbsPath: The Absolute path of the distribution file if existed, None else
323 def GetFullPathDist(DistFile
, WorkspaceDir
):
324 if os
.path
.isabs(DistFile
):
325 if not (os
.path
.exists(DistFile
) and os
.path
.isfile(DistFile
)):
330 AbsPath
= os
.path
.normpath(os
.path
.join(os
.getcwd(), DistFile
))
331 if not (os
.path
.exists(AbsPath
) and os
.path
.isfile(AbsPath
)):
332 AbsPath
= os
.path
.normpath(os
.path
.join(WorkspaceDir
, DistFile
))
333 if not (os
.path
.exists(AbsPath
) and os
.path
.isfile(AbsPath
)):
338 if __name__
== '__main__':
341 # 0-127 is a safe return range, and 1 is a standard default error
343 if RETVAL
< 0 or RETVAL
> 127: