• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1## @file
2#
3# This file is the main entry for UPT
4#
5# Copyright (c) 2011 - 2016, 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'''
17UPT
18'''
19
20## import modules
21#
22from Core import FileHook
23import sys
24import os.path
25from sys import platform
26import platform as pf
27from optparse import OptionParser
28from traceback import format_exc
29from platform import python_version
30
31from Logger import StringTable as ST
32import Logger.Log as Logger
33from Logger.StringTable import MSG_VERSION
34from Logger.StringTable import MSG_DESCRIPTION
35from Logger.StringTable import MSG_USAGE
36from Logger.ToolError import FILE_NOT_FOUND
37from Logger.ToolError import OPTION_MISSING
38from Logger.ToolError import FILE_TYPE_MISMATCH
39from Logger.ToolError import OPTION_CONFLICT
40from Logger.ToolError import FatalError
41from Logger.ToolError import UPT_ALREADY_INSTALLED_ERROR
42from Common.MultipleWorkspace import MultipleWorkspace as mws
43
44import MkPkg
45import InstallPkg
46import RmPkg
47import InventoryWs
48import ReplacePkg
49import TestInstall
50from Library.Misc import GetWorkspace
51from Library import GlobalData
52from Core.IpiDb import IpiDatabase
53from BuildVersion import gBUILD_VERSION
54
55## CheckConflictOption
56#
57# CheckConflictOption
58#
59def 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#
83def 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 != 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#
103def 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="store", 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, 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    # Start *********************************************
183    # Support WORKSPACE is a long path
184    # Only work well on windows
185    # Linux Solution TBD
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 ***********************************************
191
192    WorkspaceDir = GlobalData.gWORKSPACE
193
194    SetLogLevel(Opt)
195
196    Mgr = FileHook.RecoverMgr(WorkspaceDir)
197    FileHook.SetRecoverMgr(Mgr)
198
199    GlobalData.gDB = IpiDatabase(os.path.normpath(os.path.join(WorkspaceDir, \
200                                                               "Conf/DistributionPackageDatabase.db")), WorkspaceDir)
201    GlobalData.gDB.InitDatabase(Opt.SkipLock)
202
203    #
204    # Make sure the Db will get closed correctly
205    #
206    try:
207        ReturnCode = 0
208        CheckConflictOption(Opt)
209
210        RunModule = None
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)
216                    else:
217                        Opt.PackageInformationDataFile = os.path.join(WorkspaceDir, Opt.PackageInformationDataFile)
218            else:
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
223
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)
227
228            AbsPath = GetFullPathDist(Opt.PackFileToInstall, WorkspaceDir)
229            if not AbsPath:
230                Logger.Error("InstallPkg", FILE_NOT_FOUND, ST.ERR_INSTALL_DIST_NOT_FOUND % Opt.PackFileToInstall)
231
232            Opt.PackFileToInstall = AbsPath
233            setattr(Opt, 'PackageFile', Opt.PackFileToInstall)
234            RunModule = InstallPkg.Main
235
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)
240            if head or not tail:
241                Logger.Error("RemovePkg",
242                             FILE_TYPE_MISMATCH,
243                             ExtraData=ST.ERR_DIST_FILENAME_ONLY_FOR_REMOVE % Opt.PackFileToRemove)
244
245            setattr(Opt, 'DistributionFile', Opt.PackFileToRemove)
246            RunModule = RmPkg.Main
247        elif Opt.InventoryWs:
248            RunModule = InventoryWs.Main
249
250        elif Opt.PackFileToBeReplaced and not Opt.PackFileToReplace:
251            Logger.Error("ReplacePkg", OPTION_MISSING, ExtraData=ST.ERR_REQUIRE_U_OPTION)
252
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",
260                             FILE_TYPE_MISMATCH,
261                             ExtraData=ST.ERR_DIST_EXT_ERROR % Opt.PackFileToBeReplaced)
262
263            head, tail = os.path.split(Opt.PackFileToBeReplaced)
264            if head or not tail:
265                Logger.Error("ReplacePkg",
266                             FILE_TYPE_MISMATCH,
267                             ExtraData=ST.ERR_DIST_FILENAME_ONLY_FOR_REPLACE_ORIG % Opt.PackFileToBeReplaced)
268
269            AbsPath = GetFullPathDist(Opt.PackFileToReplace, WorkspaceDir)
270            if not AbsPath:
271                Logger.Error("ReplacePkg", FILE_NOT_FOUND, ST.ERR_REPLACE_DIST_NOT_FOUND % Opt.PackFileToReplace)
272
273            Opt.PackFileToReplace = AbsPath
274            RunModule = ReplacePkg.Main
275
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)
280
281            setattr(Opt, 'DistFiles', Opt.Test_Install_Distribution_Package_Files)
282            RunModule = TestInstall.Main
283
284        else:
285            Parser.print_usage()
286            return OPTION_MISSING
287
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) + \
293                         format_exc())
294    finally:
295        try:
296            if ReturnCode != 0 and ReturnCode != UPT_ALREADY_INSTALLED_ERROR:
297                Logger.Quiet(ST.MSG_RECOVER_START)
298                GlobalData.gDB.RollBack()
299                Mgr.rollback()
300                Logger.Quiet(ST.MSG_RECOVER_DONE)
301            else:
302                GlobalData.gDB.Commit()
303                Mgr.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')
309
310    return ReturnCode
311
312## GetFullPathDist
313#
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
316#
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
320#
321def GetFullPathDist(DistFile, WorkspaceDir):
322    if os.path.isabs(DistFile):
323        if not (os.path.exists(DistFile) and os.path.isfile(DistFile)):
324            return None
325        else:
326            return DistFile
327    else:
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)):
332                return None
333
334        return AbsPath
335
336if __name__ == '__main__':
337    RETVAL = Main()
338    #
339    # 0-127 is a safe return range, and 1 is a standard default error
340    #
341    if RETVAL < 0 or RETVAL > 127:
342        RETVAL = 1
343    sys.exit(RETVAL)
344