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
49 from Library
.Misc
import GetWorkspace
50 from Library
import GlobalData
51 from Core
.IpiDb
import IpiDatabase
52 from BuildVersion
import gBUILD_VERSION
54 ## CheckConflictOption
58 def CheckConflictOption(Opt
):
59 if (Opt
.PackFileToCreate
or Opt
.PackFileToInstall
or Opt
.PackFileToRemove
or Opt
.PackFileToReplace
) \
61 Logger
.Error("UPT", OPTION_CONFLICT
, ExtraData
=ST
.ERR_L_OA_EXCLUSIVE
)
62 elif Opt
.PackFileToReplace
and (Opt
.PackFileToCreate
or Opt
.PackFileToInstall
or Opt
.PackFileToRemove
):
63 Logger
.Error("UPT", OPTION_CONFLICT
, ExtraData
=ST
.ERR_U_ICR_EXCLUSIVE
)
64 elif (Opt
.PackFileToCreate
and Opt
.PackFileToInstall
and Opt
.PackFileToRemove
):
65 Logger
.Error("UPT", OPTION_CONFLICT
, ExtraData
=ST
.ERR_REQUIRE_I_C_R_OPTION
)
66 elif Opt
.PackFileToCreate
and Opt
.PackFileToInstall
:
67 Logger
.Error("UPT", OPTION_CONFLICT
, ExtraData
=ST
.ERR_I_C_EXCLUSIVE
)
68 elif Opt
.PackFileToInstall
and Opt
.PackFileToRemove
:
69 Logger
.Error("UPT", OPTION_CONFLICT
, ExtraData
=ST
.ERR_I_R_EXCLUSIVE
)
70 elif Opt
.PackFileToCreate
and Opt
.PackFileToRemove
:
71 Logger
.Error("UPT", OPTION_CONFLICT
, ExtraData
=ST
.ERR_C_R_EXCLUSIVE
)
73 if Opt
.CustomPath
and Opt
.UseGuidedPkgPath
:
74 Logger
.Warn("UPT", ST
.WARN_CUSTOMPATH_OVERRIDE_USEGUIDEDPATH
)
75 Opt
.UseGuidedPkgPath
= False
81 Logger
.SetLevel(Logger
.VERBOSE
)
83 Logger
.SetLevel(Logger
.QUIET
+ 1)
84 elif Opt
.debug_level
!= None:
85 if Opt
.debug_level
< 0 or Opt
.debug_level
> 9:
86 Logger
.Warn("UPT", ST
.ERR_DEBUG_LEVEL
)
87 Logger
.SetLevel(Logger
.INFO
)
89 Logger
.SetLevel(Opt
.debug_level
+ 1)
91 Logger
.SetLevel(Logger
.SILENT
)
93 Logger
.SetLevel(Logger
.INFO
)
102 Parser
= OptionParser(version
=(MSG_VERSION
+ ' Build ' + gBUILD_VERSION
), description
=MSG_DESCRIPTION
,
103 prog
="UPT.exe", usage
=MSG_USAGE
)
105 Parser
.add_option("-d", "--debug", action
="store", type="int", dest
="debug_level", help=ST
.HLP_PRINT_DEBUG_INFO
)
107 Parser
.add_option("-v", "--verbose", action
="store_true", dest
="opt_verbose",
108 help=ST
.HLP_PRINT_INFORMATIONAL_STATEMENT
)
110 Parser
.add_option("-s", "--silent", action
="store_true", dest
="opt_slient", help=ST
.HLP_RETURN_NO_DISPLAY
)
112 Parser
.add_option("-q", "--quiet", action
="store_true", dest
="opt_quiet", help=ST
.HLP_RETURN_AND_DISPLAY
)
114 Parser
.add_option("-i", "--install", action
="store", type="string", dest
="Install_Distribution_Package_File",
115 help=ST
.HLP_SPECIFY_PACKAGE_NAME_INSTALL
)
117 Parser
.add_option("-c", "--create", action
="store", type="string", dest
="Create_Distribution_Package_File",
118 help=ST
.HLP_SPECIFY_PACKAGE_NAME_CREATE
)
120 Parser
.add_option("-r", "--remove", action
="store", type="string", dest
="Remove_Distribution_Package_File",
121 help=ST
.HLP_SPECIFY_PACKAGE_NAME_REMOVE
)
123 Parser
.add_option("-t", "--template", action
="store", type="string", dest
="Package_Information_Data_File",
124 help=ST
.HLP_SPECIFY_TEMPLATE_NAME_CREATE
)
126 Parser
.add_option("-p", "--dec-filename", action
="append", type="string", dest
="EDK2_DEC_Filename",
127 help=ST
.HLP_SPECIFY_DEC_NAME_CREATE
)
129 Parser
.add_option("-m", "--inf-filename", action
="append", type="string", dest
="EDK2_INF_Filename",
130 help=ST
.HLP_SPECIFY_INF_NAME_CREATE
)
132 Parser
.add_option("-l", "--list", action
="store_true", dest
="List_Dist_Installed",
133 help=ST
.HLP_LIST_DIST_INSTALLED
)
135 Parser
.add_option("-f", "--force", action
="store_true", dest
="Yes", help=ST
.HLP_DISABLE_PROMPT
)
137 Parser
.add_option("-n", "--custom-path", action
="store_true", dest
="CustomPath", help=ST
.HLP_CUSTOM_PATH_PROMPT
)
139 Parser
.add_option("-x", "--free-lock", action
="store_true", dest
="SkipLock", help=ST
.HLP_SKIP_LOCK_CHECK
)
141 Parser
.add_option("-u", "--replace", action
="store", type="string", dest
="Replace_Distribution_Package_File",
142 help=ST
.HLP_SPECIFY_PACKAGE_NAME_REPLACE
)
144 Parser
.add_option("-o", "--original", action
="store", type="string", dest
="Original_Distribution_Package_File",
145 help=ST
.HLP_SPECIFY_PACKAGE_NAME_TO_BE_REPLACED
)
147 Parser
.add_option("--use-guided-paths", action
="store_true", dest
="Use_Guided_Paths", help=ST
.HLP_USE_GUIDED_PATHS
)
149 Opt
= Parser
.parse_args()[0]
152 ("PackageInformationDataFile", Opt
.Package_Information_Data_File
),
153 ("PackFileToInstall", Opt
.Install_Distribution_Package_File
),
154 ("PackFileToCreate", Opt
.Create_Distribution_Package_File
),
155 ("PackFileToRemove", Opt
.Remove_Distribution_Package_File
),
156 ("PackageFileList", Opt
.EDK2_DEC_Filename
),
157 ("ModuleFileList", Opt
.EDK2_INF_Filename
),
158 ("InventoryWs", Opt
.List_Dist_Installed
),
159 ("PackFileToReplace", Opt
.Replace_Distribution_Package_File
),
160 ("PackFileToBeReplaced", Opt
.Original_Distribution_Package_File
),
161 ("UseGuidedPkgPath", Opt
.Use_Guided_Paths
),
165 setattr(Opt
, Var
[0], Var
[1])
168 GlobalData
.gWORKSPACE
, GlobalData
.gPACKAGE_PATH
= GetWorkspace()
169 except FatalError
, XExcept
:
170 if Logger
.GetLevel() <= Logger
.DEBUG_9
:
171 Logger
.Quiet(ST
.MSG_PYTHON_ON
% (python_version(), platform
) + format_exc())
172 return XExcept
.args
[0]
174 # Start *********************************************
175 # Support WORKSPACE is a long path
176 # Only work well on windows
178 if pf
.system() == 'Windows':
179 os
.system('@echo off\nsubst b: /D')
180 os
.system('subst b: "%s"' % GlobalData
.gWORKSPACE
)
181 GlobalData
.gWORKSPACE
= 'B:\\'
182 # End ***********************************************
184 WorkspaceDir
= GlobalData
.gWORKSPACE
188 Mgr
= FileHook
.RecoverMgr(WorkspaceDir
)
189 FileHook
.SetRecoverMgr(Mgr
)
191 GlobalData
.gDB
= IpiDatabase(os
.path
.normpath(os
.path
.join(WorkspaceDir
, \
192 "Conf/DistributionPackageDatabase.db")), WorkspaceDir
)
193 GlobalData
.gDB
.InitDatabase(Opt
.SkipLock
)
196 # Make sure the Db will get closed correctly
200 CheckConflictOption(Opt
)
203 if Opt
.PackFileToCreate
:
204 if Opt
.PackageInformationDataFile
:
205 if not os
.path
.exists(Opt
.PackageInformationDataFile
):
206 if not os
.path
.exists(os
.path
.join(WorkspaceDir
, Opt
.PackageInformationDataFile
)):
207 Logger
.Error("\nUPT", FILE_NOT_FOUND
, ST
.ERR_NO_TEMPLATE_FILE
% Opt
.PackageInformationDataFile
)
209 Opt
.PackageInformationDataFile
= os
.path
.join(WorkspaceDir
, Opt
.PackageInformationDataFile
)
211 Logger
.Error("UPT", OPTION_MISSING
, ExtraData
=ST
.ERR_REQUIRE_T_OPTION
)
212 if not Opt
.PackFileToCreate
.endswith('.dist'):
213 Logger
.Error("CreatePkg", FILE_TYPE_MISMATCH
, ExtraData
=ST
.ERR_DIST_EXT_ERROR
% Opt
.PackFileToCreate
)
214 RunModule
= MkPkg
.Main
216 elif Opt
.PackFileToInstall
:
217 if not Opt
.PackFileToInstall
.endswith('.dist'):
218 Logger
.Error("InstallPkg", FILE_TYPE_MISMATCH
, ExtraData
=ST
.ERR_DIST_EXT_ERROR
% Opt
.PackFileToInstall
)
220 AbsPath
= GetFullPathDist(Opt
.PackFileToInstall
, WorkspaceDir
)
222 Logger
.Error("InstallPkg", FILE_NOT_FOUND
, ST
.ERR_INSTALL_DIST_NOT_FOUND
% Opt
.PackFileToInstall
)
224 Opt
.PackFileToInstall
= AbsPath
225 setattr(Opt
, 'PackageFile', Opt
.PackFileToInstall
)
226 RunModule
= InstallPkg
.Main
228 elif Opt
.PackFileToRemove
:
229 if not Opt
.PackFileToRemove
.endswith('.dist'):
230 Logger
.Error("RemovePkg", FILE_TYPE_MISMATCH
, ExtraData
=ST
.ERR_DIST_EXT_ERROR
% Opt
.PackFileToRemove
)
231 head
, tail
= os
.path
.split(Opt
.PackFileToRemove
)
233 Logger
.Error("RemovePkg",
235 ExtraData
=ST
.ERR_DIST_FILENAME_ONLY_FOR_REMOVE
% Opt
.PackFileToRemove
)
237 setattr(Opt
, 'DistributionFile', Opt
.PackFileToRemove
)
238 RunModule
= RmPkg
.Main
239 elif Opt
.InventoryWs
:
240 RunModule
= InventoryWs
.Main
242 elif Opt
.PackFileToBeReplaced
and not Opt
.PackFileToReplace
:
243 Logger
.Error("ReplacePkg", OPTION_MISSING
, ExtraData
=ST
.ERR_REQUIRE_U_OPTION
)
245 elif Opt
.PackFileToReplace
:
246 if not Opt
.PackFileToReplace
.endswith('.dist'):
247 Logger
.Error("ReplacePkg", FILE_TYPE_MISMATCH
, ExtraData
=ST
.ERR_DIST_EXT_ERROR
% Opt
.PackFileToReplace
)
248 if not Opt
.PackFileToBeReplaced
:
249 Logger
.Error("ReplacePkg", OPTION_MISSING
, ExtraData
=ST
.ERR_REQUIRE_O_OPTION
)
250 if not Opt
.PackFileToBeReplaced
.endswith('.dist'):
251 Logger
.Error("ReplacePkg",
253 ExtraData
=ST
.ERR_DIST_EXT_ERROR
% Opt
.PackFileToBeReplaced
)
255 head
, tail
= os
.path
.split(Opt
.PackFileToBeReplaced
)
257 Logger
.Error("ReplacePkg",
259 ExtraData
=ST
.ERR_DIST_FILENAME_ONLY_FOR_REPLACE_ORIG
% Opt
.PackFileToBeReplaced
)
261 AbsPath
= GetFullPathDist(Opt
.PackFileToReplace
, WorkspaceDir
)
263 Logger
.Error("ReplacePkg", FILE_NOT_FOUND
, ST
.ERR_REPLACE_DIST_NOT_FOUND
% Opt
.PackFileToReplace
)
265 Opt
.PackFileToReplace
= AbsPath
266 RunModule
= ReplacePkg
.Main
270 return OPTION_MISSING
272 ReturnCode
= RunModule(Opt
)
273 except FatalError
, XExcept
:
274 ReturnCode
= XExcept
.args
[0]
275 if Logger
.GetLevel() <= Logger
.DEBUG_9
:
276 Logger
.Quiet(ST
.MSG_PYTHON_ON
% (python_version(), platform
) + \
280 if ReturnCode
!= 0 and ReturnCode
!= UPT_ALREADY_INSTALLED_ERROR
:
281 Logger
.Quiet(ST
.MSG_RECOVER_START
)
282 GlobalData
.gDB
.RollBack()
284 Logger
.Quiet(ST
.MSG_RECOVER_DONE
)
286 GlobalData
.gDB
.Commit()
288 except StandardError:
289 Logger
.Quiet(ST
.MSG_RECOVER_FAIL
)
290 GlobalData
.gDB
.CloseDb()
291 if pf
.system() == 'Windows':
292 os
.system('subst b: /D')
298 # This function will check DistFile existence, if not absolute path, then try current working directory,
299 # then $(WORKSPACE),and return the AbsPath. If file doesn't find, then return None
301 # @param DistFile: The distribution file in either relative path or absolute path
302 # @param WorkspaceDir: Workspace Directory
303 # @return AbsPath: The Absolute path of the distribution file if existed, None else
305 def GetFullPathDist(DistFile
, WorkspaceDir
):
306 if os
.path
.isabs(DistFile
):
307 if not (os
.path
.exists(DistFile
) and os
.path
.isfile(DistFile
)):
312 AbsPath
= os
.path
.normpath(os
.path
.join(os
.getcwd(), DistFile
))
313 if not (os
.path
.exists(AbsPath
) and os
.path
.isfile(AbsPath
)):
314 AbsPath
= os
.path
.normpath(os
.path
.join(WorkspaceDir
, DistFile
))
315 if not (os
.path
.exists(AbsPath
) and os
.path
.isfile(AbsPath
)):
320 if __name__
== '__main__':
323 # 0-127 is a safe return range, and 1 is a standard default error
325 if RETVAL
< 0 or RETVAL
> 127: