2 # Install distribution package.
4 # Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
6 # This program and the accompanying materials are licensed and made available
7 # under the terms and conditions of the BSD License which accompanies this
8 # distribution. The full text of the license may be found at
9 # http://opensource.org/licenses/bsd-license.php
11 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
23 from stat
import S_IWUSR
24 from traceback
import format_exc
25 from platform
import python_version
28 from sys
import platform
30 from Core
.DependencyRules
import DependencyRules
31 from Library
.Misc
import CheckEnvVariable
32 from Library
import GlobalData
33 from Logger
import StringTable
as ST
34 import Logger
.Log
as Logger
35 from Logger
.ToolError
import OPTION_MISSING
36 from Logger
.ToolError
import UNKNOWN_ERROR
37 from Logger
.ToolError
import ABORT_ERROR
38 from Logger
.ToolError
import CODE_ERROR
39 from Logger
.ToolError
import FatalError
44 # Check if the Depex is satisfied
46 # @param Guid: Guid of Dp
47 # @param Version: Version of Dp
48 # @param WorkspaceDir: Workspace Dir
50 def CheckDpDepex(Dep
, Guid
, Version
, WorkspaceDir
):
51 (Removable
, DependModuleList
) = Dep
.CheckDpDepexForRemove(Guid
, Version
)
53 Logger
.Info(ST
.MSG_CONFIRM_REMOVE
)
54 Logger
.Info(ST
.MSG_USER_DELETE_OP
)
55 Input
= stdin
.readline()
56 Input
= Input
.replace('\r', '').replace('\n', '')
57 if Input
.upper() != 'Y':
58 Logger
.Error("RmPkg", UNKNOWN_ERROR
, ST
.ERR_USER_INTERRUPT
)
62 # report list of modules that are not valid due to force
64 # also generate a log file for reference
66 Logger
.Info(ST
.MSG_INVALID_MODULE_INTRODUCED
)
67 LogFilePath
= os
.path
.normpath(os
.path
.join(WorkspaceDir
, GlobalData
.gINVALID_MODULE_FILE
))
68 Logger
.Info(ST
.MSG_CHECK_LOG_FILE
% LogFilePath
)
70 LogFile
= open(LogFilePath
, 'w')
72 for ModulePath
in DependModuleList
:
73 LogFile
.write("%s\n"%ModulePath
)
74 Logger
.Info(ModulePath
)
76 Logger
.Warn("\nRmPkg", ST
.ERR_FILE_WRITE_FAILURE
,
79 Logger
.Warn("\nRmPkg", ST
.ERR_FILE_OPEN_FAILURE
,
86 # removing readonly file on windows will get "Access is denied"
87 # error, so before removing, change the mode to be writeable
89 # @param Path: The Path to be removed
92 Logger
.Info(ST
.MSG_REMOVE_FILE
% Path
)
93 if not os
.access(Path
, os
.W_OK
):
94 os
.chmod(Path
, S_IWUSR
)
97 os
.removedirs(os
.path
.split(Path
)[0])
100 ## GetCurrentFileList
102 # @param DataBase: DataBase of UPT
103 # @param Guid: Guid of Dp
104 # @param Version: Version of Dp
105 # @param WorkspaceDir: Workspace Dir
107 def GetCurrentFileList(DataBase
, Guid
, Version
, WorkspaceDir
):
109 for Dir
in DataBase
.GetDpInstallDirList(Guid
, Version
):
110 RootDir
= os
.path
.normpath(os
.path
.join(WorkspaceDir
, Dir
))
111 for Root
, Dirs
, Files
in os
.walk(RootDir
):
112 Logger
.Debug(0, Dirs
)
114 FilePath
= os
.path
.join(Root
, File
)
115 if FilePath
not in NewFileList
:
116 NewFileList
.append(FilePath
)
120 ## Tool entrance method
122 # This method mainly dispatch specific methods per the command line options.
123 # If no error found, return zero value so the caller of this tool can know
124 # if it's executed successfully or not.
126 # @param Options: command option
128 def Main(Options
= None):
131 DataBase
= GlobalData
.gDB
132 if not Options
.DistributionFile
:
133 Logger
.Error("RmPkg",
135 ExtraData
=ST
.ERR_SPECIFY_PACKAGE
)
137 WorkspaceDir
= GlobalData
.gWORKSPACE
139 # Prepare check dependency
141 Dep
= DependencyRules(DataBase
)
143 if Options
.DistributionFile
:
144 (Guid
, Version
, NewDpFileName
) = \
145 DataBase
.GetDpByName(os
.path
.split(Options
.DistributionFile
)[1])
147 Logger
.Error("RmPkg", UNKNOWN_ERROR
, ST
.ERR_PACKAGE_NOT_INSTALLED
% Options
.DistributionFile
)
149 Guid
= Options
.PackageGuid
150 Version
= Options
.PackageVersion
154 if not Dep
.CheckDpExists(Guid
, Version
):
155 Logger
.Error("RmPkg", UNKNOWN_ERROR
, ST
.ERR_DISTRIBUTION_NOT_INSTALLED
)
157 # Check for Distribution files existence in /conf/upt, if not exist,
158 # Warn user and go on.
160 StoredDistFile
= os
.path
.normpath(os
.path
.join(WorkspaceDir
, GlobalData
.gUPT_DIR
, NewDpFileName
))
161 if not os
.path
.isfile(StoredDistFile
):
162 Logger
.Warn("RmPkg", ST
.WRN_DIST_NOT_FOUND
%StoredDistFile
)
163 StoredDistFile
= None
168 CheckDpDepex(Dep
, Guid
, Version
, WorkspaceDir
)
171 # Get Current File List
173 NewFileList
= GetCurrentFileList(DataBase
, Guid
, Version
, WorkspaceDir
)
179 for (Path
, Md5Sum
) in DataBase
.GetDpFileList(Guid
, Version
):
180 if os
.path
.isfile(Path
):
181 if Path
in NewFileList
:
182 NewFileList
.remove(Path
)
185 # check whether modified by users
187 Md5Sigature
= md5
.new(open(str(Path
), 'rb').read())
188 if Md5Sum
!= Md5Sigature
.hexdigest():
189 Logger
.Info(ST
.MSG_CONFIRM_REMOVE2
% Path
)
190 Input
= stdin
.readline()
191 Input
= Input
.replace('\r', '').replace('\n', '')
192 if Input
.upper() != 'Y':
196 MissingFileList
.append(Path
)
198 for Path
in NewFileList
:
199 if os
.path
.isfile(Path
):
200 if (not Options
.Yes
) and (not os
.path
.split(Path
)[1].startswith('.')):
201 Logger
.Info(ST
.MSG_CONFIRM_REMOVE3
% Path
)
202 Input
= stdin
.readline()
203 Input
= Input
.replace('\r', '').replace('\n', '')
204 if Input
.upper() != 'Y':
209 # Remove distribution files in /Conf/.upt
211 if StoredDistFile
is not None:
212 os
.remove(StoredDistFile
)
217 Logger
.Quiet(ST
.MSG_UPDATE_PACKAGE_DATABASE
)
218 DataBase
.RemoveDpObj(Guid
, Version
)
219 Logger
.Quiet(ST
.MSG_FINISH
)
223 except FatalError
, XExcept
:
224 ReturnCode
= XExcept
.args
[0]
225 if Logger
.GetLevel() <= Logger
.DEBUG_9
:
226 Logger
.Quiet(ST
.MSG_PYTHON_ON
% (python_version(), platform
) + \
228 except KeyboardInterrupt:
229 ReturnCode
= ABORT_ERROR
230 if Logger
.GetLevel() <= Logger
.DEBUG_9
:
231 Logger
.Quiet(ST
.MSG_PYTHON_ON
% (python_version(), platform
) + \
237 ST
.ERR_UNKNOWN_FATAL_REMOVING_ERR
,
238 ExtraData
=ST
.MSG_SEARCH_FOR_HELP
,
241 Logger
.Quiet(ST
.MSG_PYTHON_ON
% (python_version(), platform
) + \
243 ReturnCode
= CODE_ERROR