]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/UPT/InstallPkg.py
BaseTools/UPT: Replace os.linesep with '\r\n' when generating UNI files.
[mirror_edk2.git] / BaseTools / Source / Python / UPT / InstallPkg.py
CommitLineData
4234283c
LG
1## @file\r
2# Install distribution package.\r
3#\r
421ccda3 4# Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved.<BR>\r
4234283c
LG
5#\r
6# This program and the accompanying materials are licensed and made available \r
7# under the terms and conditions of the BSD License which accompanies this \r
8# distribution. The full text of the license may be found at \r
9# http://opensource.org/licenses/bsd-license.php\r
10#\r
11# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13#\r
14"""\r
15Install a distribution package\r
16"""\r
17##\r
18# Import Modules\r
19#\r
421ccda3 20from Core.FileHook import __FileHookOpen__\r
4234283c
LG
21import os.path\r
22from os import chmod\r
23from os import SEEK_SET\r
24from os import SEEK_END\r
25import stat\r
26import md5\r
421ccda3 27import copy\r
4234283c
LG
28from sys import stdin\r
29from sys import platform\r
30from shutil import rmtree\r
31from shutil import copyfile\r
32from traceback import format_exc\r
33from platform import python_version\r
34\r
35from Logger import StringTable as ST\r
36from Logger.ToolError import UNKNOWN_ERROR\r
37from Logger.ToolError import FILE_UNKNOWN_ERROR\r
38from Logger.ToolError import OPTION_MISSING\r
39from Logger.ToolError import UPT_ALREADY_INSTALLED_ERROR\r
40from Logger.ToolError import FatalError\r
41from Logger.ToolError import ABORT_ERROR\r
42from Logger.ToolError import CODE_ERROR\r
43from Logger.ToolError import FORMAT_INVALID\r
44from Logger.ToolError import FILE_TYPE_MISMATCH\r
45import Logger.Log as Logger\r
46\r
4234283c
LG
47from Library.Misc import Sdict\r
48from Library.Misc import ConvertPath\r
49from Library.ParserValidate import IsValidInstallPath\r
50from Xml.XmlParser import DistributionPackageXml\r
51from GenMetaFile.GenDecFile import PackageToDec\r
52from GenMetaFile.GenInfFile import ModuleToInf\r
53from Core.PackageFile import PackageFile\r
54from Core.PackageFile import FILE_NOT_FOUND\r
55from Core.PackageFile import FILE_CHECKSUM_FAILURE\r
56from Core.PackageFile import CreateDirectory\r
57from Core.DependencyRules import DependencyRules\r
58from Library import GlobalData\r
59\r
60## InstallNewPackage\r
61#\r
62# @param WorkspaceDir: Workspace Directory\r
63# @param Path: Package Path\r
64# @param CustomPath: whether need to customize path at first\r
65#\r
66def InstallNewPackage(WorkspaceDir, Path, CustomPath = False):\r
67 if os.path.isabs(Path):\r
68 Logger.Info(ST.MSG_RELATIVE_PATH_ONLY%Path)\r
69 elif CustomPath:\r
70 Logger.Info(ST.MSG_NEW_PKG_PATH)\r
71 else:\r
72 Path = ConvertPath(Path)\r
73 Path = os.path.normpath(Path)\r
74 FullPath = os.path.normpath(os.path.join(WorkspaceDir, Path))\r
75 if os.path.exists(FullPath):\r
76 Logger.Info(ST.ERR_DIR_ALREADY_EXIST%FullPath)\r
77 else:\r
78 return Path\r
79\r
80 Input = stdin.readline()\r
81 Input = Input.replace('\r', '').replace('\n', '')\r
82 if Input == '':\r
83 Logger.Error("InstallPkg", UNKNOWN_ERROR, ST.ERR_USER_INTERRUPT)\r
84 Input = Input.replace('\r', '').replace('\n', '')\r
85 return InstallNewPackage(WorkspaceDir, Input, False)\r
86\r
4234283c
LG
87## InstallNewModule\r
88#\r
89# @param WorkspaceDir: Workspace Directory\r
90# @param Path: Standalone Module Path\r
91# @param PathList: The already installed standalone module Path list\r
92#\r
93def InstallNewModule(WorkspaceDir, Path, PathList = None):\r
94 if PathList == None:\r
95 PathList = []\r
96 Path = ConvertPath(Path)\r
97 Path = os.path.normpath(Path)\r
98 FullPath = os.path.normpath(os.path.join(WorkspaceDir, Path))\r
99 if os.path.exists(FullPath) and FullPath not in PathList:\r
100 Logger.Info(ST.ERR_DIR_ALREADY_EXIST%Path)\r
101 elif Path == FullPath:\r
102 Logger.Info(ST.MSG_RELATIVE_PATH_ONLY%FullPath)\r
103 else:\r
104 return Path\r
105 \r
106 Input = stdin.readline()\r
107 Input = Input.replace('\r', '').replace('\n', '')\r
108 if Input == '':\r
109 Logger.Error("InstallPkg", UNKNOWN_ERROR, ST.ERR_USER_INTERRUPT)\r
110 Input = Input.replace('\r', '').replace('\n', '')\r
111 return InstallNewModule(WorkspaceDir, Input, PathList)\r
112\r
113 \r
114## InstallNewFile\r
115#\r
116# @param WorkspaceDir: Workspace Direction\r
117# @param File: File\r
118#\r
119def InstallNewFile(WorkspaceDir, File):\r
120 FullPath = os.path.normpath(os.path.join(WorkspaceDir, File))\r
121 if os.path.exists(FullPath):\r
122 Logger.Info(ST.ERR_FILE_ALREADY_EXIST %File)\r
123 Input = stdin.readline()\r
124 Input = Input.replace('\r', '').replace('\n', '')\r
125 if Input == '':\r
126 Logger.Error("InstallPkg", UNKNOWN_ERROR, ST.ERR_USER_INTERRUPT)\r
127 Input = Input.replace('\r', '').replace('\n', '')\r
128 return InstallNewFile(WorkspaceDir, Input)\r
129 else:\r
130 return File\r
131\r
132## UnZipDp\r
133#\r
134# UnZipDp\r
135#\r
421ccda3 136def UnZipDp(WorkspaceDir, DpPkgFileName):\r
4234283c
LG
137 ContentZipFile = None\r
138 Logger.Quiet(ST.MSG_UZIP_PARSE_XML)\r
4234283c
LG
139 DistFile = PackageFile(DpPkgFileName)\r
140 \r
141 DpDescFileName, ContentFileName = GetDPFile(DistFile.GetZipFile())\r
142 \r
143 GlobalData.gUNPACK_DIR = os.path.normpath(os.path.join(WorkspaceDir, ".tmp"))\r
144 DistPkgFile = DistFile.UnpackFile(DpDescFileName,\r
145 os.path.normpath(os.path.join(GlobalData.gUNPACK_DIR, DpDescFileName)))\r
146 if not DistPkgFile:\r
147 Logger.Error("InstallPkg", FILE_NOT_FOUND, ST.ERR_FILE_BROKEN %DpDescFileName)\r
148 \r
149 #\r
150 # Generate distpkg\r
151 #\r
152 DistPkgObj = DistributionPackageXml()\r
153 DistPkg = DistPkgObj.FromXml(DistPkgFile)\r
154 if DistPkg.Header.RePackage == '':\r
155 DistPkg.Header.RePackage = False\r
156 if DistPkg.Header.ReadOnly == '':\r
157 DistPkg.Header.ReadOnly = False\r
421ccda3 158\r
4234283c
LG
159 #\r
160 # unzip contents.zip file\r
161 #\r
162 ContentFile = DistFile.UnpackFile(ContentFileName,\r
163 os.path.normpath(os.path.join(GlobalData.gUNPACK_DIR, ContentFileName)))\r
164 if not ContentFile:\r
165 Logger.Error("InstallPkg", FILE_NOT_FOUND,\r
166 ST.ERR_FILE_BROKEN % ContentFileName)\r
167\r
421ccda3 168 FilePointer = __FileHookOpen__(ContentFile, "rb")\r
4234283c
LG
169 #\r
170 # Assume no archive comment.\r
171 #\r
172 FilePointer.seek(0, SEEK_SET)\r
173 FilePointer.seek(0, SEEK_END)\r
174 #\r
175 # Get file size\r
176 # \r
177 FileSize = FilePointer.tell()\r
178 FilePointer.close()\r
179 \r
180 if FileSize != 0: \r
181 ContentZipFile = PackageFile(ContentFile)\r
182\r
183 #\r
184 # verify MD5 signature when existed\r
185 #\r
186 if DistPkg.Header.Signature != '':\r
421ccda3 187 Md5Sigature = md5.new(__FileHookOpen__(ContentFile, 'rb').read())\r
4234283c
LG
188 if DistPkg.Header.Signature != Md5Sigature.hexdigest():\r
189 ContentZipFile.Close()\r
190 Logger.Error("InstallPkg", FILE_CHECKSUM_FAILURE,\r
191 ExtraData=ContentFile)\r
192\r
421ccda3 193 return DistPkg, ContentZipFile, DpPkgFileName, DistFile\r
4234283c
LG
194\r
195## GetPackageList\r
196#\r
197# GetPackageList\r
198#\r
199def GetPackageList(DistPkg, Dep, WorkspaceDir, Options, ContentZipFile, ModuleList, PackageList):\r
200 NewDict = Sdict()\r
201 for Guid, Version, Path in DistPkg.PackageSurfaceArea:\r
202 PackagePath = Path\r
203 Package = DistPkg.PackageSurfaceArea[Guid, Version, Path]\r
204 Logger.Info(ST.MSG_INSTALL_PACKAGE % Package.GetName())\r
205 if Dep.CheckPackageExists(Guid, Version):\r
206 Logger.Info(ST.WRN_PACKAGE_EXISTED %(Guid, Version))\r
421ccda3
HC
207 if Options.UseGuidedPkgPath:\r
208 GuidedPkgPath = "%s_%s_%s" % (Package.GetName(), Guid, Version)\r
209 NewPackagePath = InstallNewPackage(WorkspaceDir, GuidedPkgPath, Options.CustomPath)\r
210 else:\r
211 NewPackagePath = InstallNewPackage(WorkspaceDir, PackagePath, Options.CustomPath)\r
4234283c
LG
212 InstallPackageContent(PackagePath, NewPackagePath, Package, ContentZipFile, Dep, WorkspaceDir, ModuleList, \r
213 DistPkg.Header.ReadOnly)\r
214 PackageList.append(Package)\r
215 \r
216 NewDict[Guid, Version, Package.GetPackagePath()] = Package\r
217 \r
218 #\r
219 # Now generate meta-data files, first generate all dec for package\r
220 # dec should be generated before inf, and inf should be generated after\r
221 # all packages installed, else hard to resolve modules' package\r
222 # dependency (Hard to get the location of the newly installed package)\r
223 #\r
224 for Package in PackageList:\r
421ccda3
HC
225 FilePath = PackageToDec(Package, DistPkg.Header)\r
226 Md5Sigature = md5.new(__FileHookOpen__(str(FilePath), 'rb').read())\r
4234283c
LG
227 Md5Sum = Md5Sigature.hexdigest()\r
228 if (FilePath, Md5Sum) not in Package.FileList:\r
229 Package.FileList.append((FilePath, Md5Sum))\r
230 \r
231 return NewDict\r
232\r
233## GetModuleList\r
234#\r
235# GetModuleList\r
236#\r
237def GetModuleList(DistPkg, Dep, WorkspaceDir, ContentZipFile, ModuleList):\r
238 #\r
239 # ModulePathList will keep track of the standalone module path that\r
240 # we just installed. If a new module's path in that list \r
241 # (only multiple INF in one directory will be so), we will \r
242 # install them directly. If not, we will try to create a new directory \r
243 # for it.\r
244 #\r
421ccda3 245 ModulePathList = []\r
4234283c
LG
246 \r
247 #\r
248 # Check module exist and install\r
249 #\r
250 Module = None\r
251 NewDict = Sdict() \r
d0acc87a 252 for Guid, Version, Name, Path in DistPkg.ModuleSurfaceArea:\r
4234283c 253 ModulePath = Path\r
d0acc87a 254 Module = DistPkg.ModuleSurfaceArea[Guid, Version, Name, Path]\r
4234283c 255 Logger.Info(ST.MSG_INSTALL_MODULE % Module.GetName())\r
d0acc87a 256 if Dep.CheckModuleExists(Guid, Version, Name, Path):\r
4234283c
LG
257 Logger.Quiet(ST.WRN_MODULE_EXISTED %Path)\r
258 #\r
259 # here check for the multiple inf share the same module path cases:\r
260 # they should be installed into the same directory\r
261 #\r
262 ModuleFullPath = \\r
263 os.path.normpath(os.path.join(WorkspaceDir, ModulePath))\r
264 if ModuleFullPath not in ModulePathList:\r
265 NewModulePath = InstallNewModule(WorkspaceDir, ModulePath, ModulePathList)\r
266 NewModuleFullPath = os.path.normpath(os.path.join(WorkspaceDir, NewModulePath))\r
267 ModulePathList.append(NewModuleFullPath)\r
268 else:\r
269 NewModulePath = ModulePath\r
270 \r
271 InstallModuleContent(ModulePath, NewModulePath, '', Module, ContentZipFile, WorkspaceDir, ModuleList, None, \r
272 DistPkg.Header.ReadOnly)\r
273 #\r
274 # Update module\r
275 #\r
276 Module.SetModulePath(Module.GetModulePath().replace(Path, NewModulePath, 1))\r
277 \r
d0acc87a 278 NewDict[Guid, Version, Name, Module.GetModulePath()] = Module\r
4234283c
LG
279\r
280 #\r
281 # generate all inf for modules\r
282 #\r
283 for (Module, Package) in ModuleList:\r
421ccda3
HC
284 CheckCNameInModuleRedefined(Module, DistPkg)\r
285 FilePath = ModuleToInf(Module, Package, DistPkg.Header)\r
286 Md5Sigature = md5.new(__FileHookOpen__(str(FilePath), 'rb').read())\r
4234283c
LG
287 Md5Sum = Md5Sigature.hexdigest()\r
288 if Package:\r
289 if (FilePath, Md5Sum) not in Package.FileList:\r
290 Package.FileList.append((FilePath, Md5Sum))\r
291 else:\r
292 if (FilePath, Md5Sum) not in Module.FileList:\r
293 Module.FileList.append((FilePath, Md5Sum))\r
421ccda3
HC
294 #\r
295 # append the module unicode files to Package FileList\r
296 #\r
297 for (FilePath, Md5Sum) in Module.FileList:\r
298 if str(FilePath).endswith('.uni') and Package and (FilePath, Md5Sum) not in Package.FileList:\r
299 Package.FileList.append((FilePath, Md5Sum))\r
4234283c
LG
300 \r
301 return NewDict\r
302\r
421ccda3
HC
303##\r
304# Get all protocol/ppi/guid CNames and pcd name from all dependent DEC file\r
305#\r
306def GetDepProtocolPpiGuidPcdNames(DePackageObjList):\r
307 #\r
308 # [[Dec1Protocol1, Dec1Protocol2...], [Dec2Protocols...],...]\r
309 #\r
310 DependentProtocolCNames = []\r
311 DependentPpiCNames = []\r
312 DependentGuidCNames = []\r
313 DependentPcdNames = []\r
314 \r
315 for PackageObj in DePackageObjList:\r
316 #\r
317 # Get protocol CName list from all dependent DEC file\r
318 #\r
319 ProtocolCNames = []\r
320 for Protocol in PackageObj.GetProtocolList():\r
321 if Protocol.GetCName() not in ProtocolCNames:\r
322 ProtocolCNames.append(Protocol.GetCName())\r
323 \r
324 DependentProtocolCNames.append(ProtocolCNames)\r
325 \r
326 #\r
327 # Get Ppi CName list from all dependent DEC file\r
328 # \r
329 PpiCNames = []\r
330 for Ppi in PackageObj.GetPpiList():\r
331 if Ppi.GetCName() not in PpiCNames:\r
332 PpiCNames.append(Ppi.GetCName())\r
333\r
334 DependentPpiCNames.append(PpiCNames)\r
335 \r
336 #\r
337 # Get Guid CName list from all dependent DEC file\r
338 # \r
339 GuidCNames = []\r
340 for Guid in PackageObj.GetGuidList():\r
341 if Guid.GetCName() not in GuidCNames:\r
342 GuidCNames.append(Guid.GetCName())\r
343 \r
344 DependentGuidCNames.append(GuidCNames)\r
345 \r
346 #\r
347 # Get PcdName list from all dependent DEC file\r
348 #\r
349 PcdNames = []\r
350 for Pcd in PackageObj.GetPcdList():\r
351 PcdName = '.'.join([Pcd.GetTokenSpaceGuidCName(), Pcd.GetCName()])\r
352 if PcdName not in PcdNames:\r
353 PcdNames.append(PcdName)\r
354 \r
355 DependentPcdNames.append(PcdNames)\r
356 \r
357 \r
358 return DependentProtocolCNames, DependentPpiCNames, DependentGuidCNames, DependentPcdNames\r
359\r
360##\r
361# Check if protocol CName is redefined\r
362#\r
363def CheckProtoclCNameRedefined(Module, DependentProtocolCNames):\r
364 for ProtocolInModule in Module.GetProtocolList():\r
365 IsCNameDefined = False\r
366 for PackageProtocolCNames in DependentProtocolCNames:\r
367 if ProtocolInModule.GetCName() in PackageProtocolCNames:\r
368 if IsCNameDefined:\r
369 Logger.Error("\nUPT", FORMAT_INVALID, \r
370 File = Module.GetFullPath(), \r
371 ExtraData = \\r
372 ST.ERR_INF_PARSER_ITEM_DUPLICATE_IN_DEC % ProtocolInModule.GetCName())\r
373 else:\r
374 IsCNameDefined = True\r
375\r
376##\r
377# Check if Ppi CName is redefined\r
378#\r
379def CheckPpiCNameRedefined(Module, DependentPpiCNames):\r
380 for PpiInModule in Module.GetPpiList():\r
381 IsCNameDefined = False\r
382 for PackagePpiCNames in DependentPpiCNames:\r
383 if PpiInModule.GetCName() in PackagePpiCNames:\r
384 if IsCNameDefined:\r
385 Logger.Error("\nUPT", FORMAT_INVALID, \r
386 File = Module.GetFullPath(), \r
387 ExtraData = ST.ERR_INF_PARSER_ITEM_DUPLICATE_IN_DEC % PpiInModule.GetCName())\r
388 else:\r
389 IsCNameDefined = True \r
390\r
391##\r
392# Check if Guid CName is redefined\r
393#\r
394def CheckGuidCNameRedefined(Module, DependentGuidCNames):\r
395 for GuidInModule in Module.GetGuidList():\r
396 IsCNameDefined = False\r
397 for PackageGuidCNames in DependentGuidCNames:\r
398 if GuidInModule.GetCName() in PackageGuidCNames:\r
399 if IsCNameDefined:\r
400 Logger.Error("\nUPT", FORMAT_INVALID, \r
401 File = Module.GetFullPath(), \r
402 ExtraData = \\r
403 ST.ERR_INF_PARSER_ITEM_DUPLICATE_IN_DEC % GuidInModule.GetCName())\r
404 else:\r
405 IsCNameDefined = True\r
406\r
407##\r
408# Check if PcdName is redefined\r
409#\r
410def CheckPcdNameRedefined(Module, DependentPcdNames):\r
411 PcdObjs = []\r
412 if not Module.GetBinaryFileList():\r
413 PcdObjs += Module.GetPcdList()\r
414 else:\r
415 Binary = Module.GetBinaryFileList()[0]\r
416 for AsBuild in Binary.GetAsBuiltList():\r
417 PcdObjs += AsBuild.GetPatchPcdList() + AsBuild.GetPcdExList()\r
418\r
419 for PcdObj in PcdObjs:\r
420 PcdName = '.'.join([PcdObj.GetTokenSpaceGuidCName(), PcdObj.GetCName()])\r
421 IsPcdNameDefined = False\r
422 for PcdNames in DependentPcdNames:\r
423 if PcdName in PcdNames:\r
424 if IsPcdNameDefined:\r
425 Logger.Error("\nUPT", FORMAT_INVALID, \r
426 File = Module.GetFullPath(), \r
427 ExtraData = ST.ERR_INF_PARSER_ITEM_DUPLICATE_IN_DEC % PcdName)\r
428 else:\r
429 IsPcdNameDefined = True\r
430\r
431##\r
432# Check if any Protocol/Ppi/Guid and Pcd name is redefined in its dependent DEC files\r
433#\r
434def CheckCNameInModuleRedefined(Module, DistPkg):\r
435 DePackageObjList = []\r
436 #\r
437 # Get all dependent package objects\r
438 # \r
439 for Obj in Module.GetPackageDependencyList():\r
440 Guid = Obj.GetGuid()\r
441 Version = Obj.GetVersion()\r
442 for Key in DistPkg.PackageSurfaceArea:\r
443 if Key[0] == Guid and Key[1] == Version:\r
444 if DistPkg.PackageSurfaceArea[Key] not in DePackageObjList:\r
445 DePackageObjList.append(DistPkg.PackageSurfaceArea[Key])\r
446 \r
447 DependentProtocolCNames, DependentPpiCNames, DependentGuidCNames, DependentPcdNames = \\r
448 GetDepProtocolPpiGuidPcdNames(DePackageObjList)\r
449\r
450 CheckProtoclCNameRedefined(Module, DependentProtocolCNames)\r
451 CheckPpiCNameRedefined(Module, DependentPpiCNames)\r
452 CheckGuidCNameRedefined(Module, DependentGuidCNames)\r
453 CheckPcdNameRedefined(Module, DependentPcdNames)\r
454\r
4234283c
LG
455## GenToolMisc\r
456#\r
457# GenToolMisc\r
458#\r
459#\r
460def GenToolMisc(DistPkg, WorkspaceDir, ContentZipFile):\r
461 ToolObject = DistPkg.Tools\r
462 MiscObject = DistPkg.MiscellaneousFiles\r
463 DistPkg.FileList = []\r
464 FileList = []\r
465 ToolFileNum = 0\r
466 FileNum = 0\r
467 RootDir = WorkspaceDir\r
468 \r
469 #\r
470 # FileList stores both tools files and misc files\r
471 # Misc file list must be appended to FileList *AFTER* Tools file list\r
472 #\r
473 if ToolObject:\r
474 FileList += ToolObject.GetFileList()\r
475 ToolFileNum = len(ToolObject.GetFileList())\r
476 if 'EDK_TOOLS_PATH' in os.environ:\r
477 RootDir = os.environ['EDK_TOOLS_PATH']\r
478 if MiscObject:\r
479 FileList += MiscObject.GetFileList()\r
480 for FileObject in FileList:\r
481 FileNum += 1\r
482 if FileNum > ToolFileNum:\r
483 #\r
484 # Misc files, root should be changed to WORKSPACE\r
485 #\r
486 RootDir = WorkspaceDir\r
487 File = ConvertPath(FileObject.GetURI())\r
488 ToFile = os.path.normpath(os.path.join(RootDir, File))\r
489 if os.path.exists(ToFile):\r
490 Logger.Info( ST.WRN_FILE_EXISTED % ToFile )\r
491 #\r
492 # ask for user input the new file name\r
493 #\r
494 Logger.Info( ST.MSG_NEW_FILE_NAME)\r
495 Input = stdin.readline()\r
496 Input = Input.replace('\r', '').replace('\n', '')\r
497 OrigPath = os.path.split(ToFile)[0]\r
498 ToFile = os.path.normpath(os.path.join(OrigPath, Input))\r
499 FromFile = os.path.join(FileObject.GetURI())\r
500 Md5Sum = InstallFile(ContentZipFile, FromFile, ToFile, DistPkg.Header.ReadOnly, FileObject.GetExecutable())\r
501 DistPkg.FileList.append((ToFile, Md5Sum))\r
502\r
503## Tool entrance method\r
504#\r
505# This method mainly dispatch specific methods per the command line options.\r
506# If no error found, return zero value so the caller of this tool can know\r
507# if it's executed successfully or not.\r
508#\r
509# @param Options: command Options\r
510#\r
511def Main(Options = None):\r
512 ContentZipFile, DistFile = None, None\r
513\r
514 try:\r
421ccda3 515 DataBase = GlobalData.gDB\r
4234283c
LG
516 WorkspaceDir = GlobalData.gWORKSPACE\r
517 if not Options.PackageFile:\r
518 Logger.Error("InstallPkg", OPTION_MISSING, ExtraData=ST.ERR_SPECIFY_PACKAGE)\r
519 \r
520 #\r
521 # unzip dist.pkg file\r
522 #\r
421ccda3 523 DistPkg, ContentZipFile, DpPkgFileName, DistFile = UnZipDp(WorkspaceDir, Options.PackageFile)\r
4234283c 524\r
4234283c 525 #\r
421ccda3 526 # check dependency\r
4234283c 527 #\r
421ccda3
HC
528 Dep = DependencyRules(DataBase)\r
529 CheckInstallDpx(Dep, DistPkg)\r
4234283c
LG
530\r
531 #\r
421ccda3 532 # Install distribution\r
4234283c 533 #\r
421ccda3 534 InstallDp(DistPkg, DpPkgFileName, ContentZipFile, Options, Dep, WorkspaceDir, DataBase)\r
4234283c
LG
535 ReturnCode = 0\r
536 \r
537 except FatalError, XExcept:\r
538 ReturnCode = XExcept.args[0]\r
539 if Logger.GetLevel() <= Logger.DEBUG_9:\r
421ccda3
HC
540 Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), platform) + format_exc())\r
541 \r
4234283c
LG
542 except KeyboardInterrupt:\r
543 ReturnCode = ABORT_ERROR\r
544 if Logger.GetLevel() <= Logger.DEBUG_9:\r
421ccda3
HC
545 Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(), platform) + format_exc())\r
546 \r
4234283c
LG
547 except:\r
548 ReturnCode = CODE_ERROR\r
549 Logger.Error(\r
550 "\nInstallPkg",\r
551 CODE_ERROR,\r
552 ST.ERR_UNKNOWN_FATAL_INSTALL_ERR % Options.PackageFile,\r
553 ExtraData=ST.MSG_SEARCH_FOR_HELP,\r
554 RaiseError=False\r
555 )\r
556 Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(),\r
557 platform) + format_exc())\r
4234283c
LG
558 finally:\r
559 Logger.Quiet(ST.MSG_REMOVE_TEMP_FILE_STARTED)\r
560 if DistFile:\r
561 DistFile.Close()\r
562 if ContentZipFile:\r
563 ContentZipFile.Close()\r
564 if GlobalData.gUNPACK_DIR:\r
565 rmtree(GlobalData.gUNPACK_DIR)\r
566 GlobalData.gUNPACK_DIR = None\r
567 Logger.Quiet(ST.MSG_REMOVE_TEMP_FILE_DONE)\r
4234283c
LG
568 if ReturnCode == 0:\r
569 Logger.Quiet(ST.MSG_FINISH)\r
4234283c
LG
570 return ReturnCode\r
571\r
421ccda3
HC
572# BackupDist method\r
573# \r
574# This method will backup the Distribution file into the $(WORKSPACE)/conf/upt, and rename it \r
575# if there is already a same-named distribution existed.\r
576#\r
577# @param DpPkgFileName: The distribution path\r
578# @param Guid: The distribution Guid\r
579# @param Version: The distribution Version\r
580# @param WorkspaceDir: The workspace directory\r
581# @retval NewDpPkgFileName: The exact backup file name\r
582#\r
583def BackupDist(DpPkgFileName, Guid, Version, WorkspaceDir):\r
584 DistFileName = os.path.split(DpPkgFileName)[1]\r
585 DestDir = os.path.normpath(os.path.join(WorkspaceDir, GlobalData.gUPT_DIR))\r
586 CreateDirectory(DestDir)\r
587 DestFile = os.path.normpath(os.path.join(DestDir, DistFileName))\r
588 if os.path.exists(DestFile):\r
589 FileName, Ext = os.path.splitext(DistFileName)\r
590 NewFileName = FileName + '_' + Guid + '_' + Version + Ext\r
591 DestFile = os.path.normpath(os.path.join(DestDir, NewFileName))\r
592 if os.path.exists(DestFile):\r
593 #\r
594 # ask for user input the new file name\r
595 #\r
596 Logger.Info( ST.MSG_NEW_FILE_NAME_FOR_DIST)\r
597 Input = stdin.readline()\r
598 Input = Input.replace('\r', '').replace('\n', '')\r
599 DestFile = os.path.normpath(os.path.join(DestDir, Input))\r
600 copyfile(DpPkgFileName, DestFile)\r
601 NewDpPkgFileName = DestFile[DestFile.find(DestDir) + len(DestDir) + 1:]\r
602 return NewDpPkgFileName\r
603\r
604## CheckInstallDpx method\r
605#\r
606# check whether distribution could be installed\r
607#\r
608# @param Dep: the DependencyRules instance that used to check dependency\r
609# @param DistPkg: the distribution object\r
610#\r
611def CheckInstallDpx(Dep, DistPkg):\r
612 #\r
613 # Check distribution package installed or not\r
614 #\r
615 if Dep.CheckDpExists(DistPkg.Header.GetGuid(),\r
616 DistPkg.Header.GetVersion()):\r
617 Logger.Error("InstallPkg", UPT_ALREADY_INSTALLED_ERROR,\r
618 ST.WRN_DIST_PKG_INSTALLED)\r
619 #\r
620 # Check distribution dependency (all module dependency should be\r
621 # satisfied)\r
622 #\r
623 if not Dep.CheckInstallDpDepexSatisfied(DistPkg):\r
624 Logger.Error("InstallPkg", UNKNOWN_ERROR,\r
625 ST.ERR_PACKAGE_NOT_MATCH_DEPENDENCY,\r
626 ExtraData=DistPkg.Header.Name)\r
627\r
4234283c
LG
628## InstallModuleContent method\r
629#\r
630# If this is standalone module, then Package should be none,\r
631# ModulePath should be ''\r
632# @param FromPath: FromPath\r
633# @param NewPath: NewPath\r
634# @param ModulePath: ModulePath\r
635# @param Module: Module\r
636# @param ContentZipFile: ContentZipFile\r
637# @param WorkspaceDir: WorkspaceDir\r
638# @param ModuleList: ModuleList\r
639# @param Package: Package\r
640#\r
641def InstallModuleContent(FromPath, NewPath, ModulePath, Module, ContentZipFile,\r
642 WorkspaceDir, ModuleList, Package = None, ReadOnly = False):\r
643 \r
644 if NewPath.startswith("\\") or NewPath.startswith("/"):\r
645 NewPath = NewPath[1:]\r
646 \r
647 if not IsValidInstallPath(NewPath):\r
648 Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%NewPath) \r
649 \r
650 NewModuleFullPath = os.path.normpath(os.path.join(WorkspaceDir, NewPath,\r
651 ConvertPath(ModulePath)))\r
652 Module.SetFullPath(os.path.normpath(os.path.join(NewModuleFullPath,\r
653 ConvertPath(Module.GetName()) + '.inf')))\r
654 Module.FileList = []\r
655 \r
656 for MiscFile in Module.GetMiscFileList():\r
657 if not MiscFile:\r
658 continue\r
659 for Item in MiscFile.GetFileList():\r
660 File = Item.GetURI()\r
661 if File.startswith("\\") or File.startswith("/"):\r
662 File = File[1:]\r
663 \r
664 if not IsValidInstallPath(File):\r
665 Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%File)\r
421ccda3 666\r
4234283c
LG
667 FromFile = os.path.join(FromPath, ModulePath, File)\r
668 Executable = Item.GetExecutable() \r
669 ToFile = os.path.normpath(os.path.join(NewModuleFullPath, ConvertPath(File)))\r
670 Md5Sum = InstallFile(ContentZipFile, FromFile, ToFile, ReadOnly, Executable)\r
671 if Package and ((ToFile, Md5Sum) not in Package.FileList):\r
672 Package.FileList.append((ToFile, Md5Sum))\r
673 elif Package:\r
674 continue\r
675 elif (ToFile, Md5Sum) not in Module.FileList:\r
676 Module.FileList.append((ToFile, Md5Sum))\r
677 for Item in Module.GetSourceFileList():\r
678 File = Item.GetSourceFile()\r
679 if File.startswith("\\") or File.startswith("/"):\r
680 File = File[1:]\r
681 \r
682 if not IsValidInstallPath(File):\r
683 Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%File) \r
684 \r
685 FromFile = os.path.join(FromPath, ModulePath, File)\r
686 ToFile = os.path.normpath(os.path.join(NewModuleFullPath, ConvertPath(File)))\r
687 Md5Sum = InstallFile(ContentZipFile, FromFile, ToFile, ReadOnly)\r
688 if Package and ((ToFile, Md5Sum) not in Package.FileList):\r
689 Package.FileList.append((ToFile, Md5Sum))\r
690 elif Package:\r
691 continue\r
692 elif (ToFile, Md5Sum) not in Module.FileList:\r
693 Module.FileList.append((ToFile, Md5Sum))\r
694 for Item in Module.GetBinaryFileList():\r
695 FileNameList = Item.GetFileNameList()\r
696 for FileName in FileNameList: \r
697 File = FileName.GetFilename() \r
698 if File.startswith("\\") or File.startswith("/"):\r
699 File = File[1:]\r
700 \r
701 if not IsValidInstallPath(File):\r
702 Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%File)\r
703\r
704 FromFile = os.path.join(FromPath, ModulePath, File)\r
705 ToFile = os.path.normpath(os.path.join(NewModuleFullPath, ConvertPath(File)))\r
706 Md5Sum = InstallFile(ContentZipFile, FromFile, ToFile, ReadOnly) \r
707 if Package and ((ToFile, Md5Sum) not in Package.FileList):\r
708 Package.FileList.append((ToFile, Md5Sum))\r
709 elif Package:\r
710 continue\r
711 elif (ToFile, Md5Sum) not in Module.FileList:\r
712 Module.FileList.append((ToFile, Md5Sum))\r
713 \r
714 InstallModuleContentZipFile(ContentZipFile, FromPath, ModulePath, WorkspaceDir, NewPath, Module, Package, ReadOnly,\r
715 ModuleList)\r
716\r
717## InstallModuleContentZipFile\r
718#\r
719# InstallModuleContentZipFile\r
720#\r
721def InstallModuleContentZipFile(ContentZipFile, FromPath, ModulePath, WorkspaceDir, NewPath, Module, Package, ReadOnly,\r
722 ModuleList):\r
723 #\r
724 # Extract other files under current module path in content Zip file but not listed in the description \r
725 #\r
726 if ContentZipFile:\r
727 for FileName in ContentZipFile.GetZipFile().namelist():\r
728 FileName = os.path.normpath(FileName)\r
729 CheckPath = os.path.normpath(os.path.join(FromPath, ModulePath))\r
730 if FileUnderPath(FileName, CheckPath):\r
731 if FileName.startswith("\\") or FileName.startswith("/"):\r
732 FileName = FileName[1:]\r
733 \r
734 if not IsValidInstallPath(FileName):\r
735 Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%FileName)\r
736 \r
737 FromFile = FileName\r
738 ToFile = os.path.normpath(os.path.join(WorkspaceDir, \r
739 ConvertPath(FileName.replace(FromPath, NewPath, 1))))\r
421ccda3 740 CheckList = copy.copy(Module.FileList)\r
4234283c
LG
741 if Package:\r
742 CheckList += Package.FileList\r
743 for Item in CheckList:\r
744 if Item[0] == ToFile:\r
745 break\r
746 else:\r
747 Md5Sum = InstallFile(ContentZipFile, FromFile, ToFile, ReadOnly)\r
748 if Package and ((ToFile, Md5Sum) not in Package.FileList):\r
749 Package.FileList.append((ToFile, Md5Sum))\r
750 elif Package:\r
751 continue\r
752 elif (ToFile, Md5Sum) not in Module.FileList:\r
753 Module.FileList.append((ToFile, Md5Sum)) \r
754 \r
755 ModuleList.append((Module, Package))\r
756\r
757## FileUnderPath\r
758# Check whether FileName started with directory specified by CheckPath \r
759#\r
760# @param FileName: the FileName need to be checked\r
761# @param CheckPath: the path need to be checked against\r
762# @return: True or False \r
763#\r
764def FileUnderPath(FileName, CheckPath):\r
765 FileName = FileName.replace('\\', '/')\r
766 FileName = os.path.normpath(FileName)\r
767 CheckPath = CheckPath.replace('\\', '/')\r
768 CheckPath = os.path.normpath(CheckPath)\r
769 if FileName.startswith(CheckPath):\r
770 RemainingPath = os.path.normpath(FileName.replace(CheckPath, '', 1))\r
771 while RemainingPath.startswith('\\') or RemainingPath.startswith('/'):\r
772 RemainingPath = RemainingPath[1:]\r
773 if FileName == os.path.normpath(os.path.join(CheckPath, RemainingPath)):\r
774 return True\r
775 \r
776 return False\r
777\r
778## InstallFile\r
779# Extract File from Zipfile, set file attribute, and return the Md5Sum\r
780#\r
781# @return: True or False \r
782#\r
783def InstallFile(ContentZipFile, FromFile, ToFile, ReadOnly, Executable=False):\r
421ccda3
HC
784 if os.path.exists(os.path.normpath(ToFile)):\r
785 pass\r
786 else:\r
787 if not ContentZipFile or not ContentZipFile.UnpackFile(FromFile, ToFile):\r
788 Logger.Error("UPT", FILE_NOT_FOUND, ST.ERR_INSTALL_FILE_FROM_EMPTY_CONTENT % FromFile)\r
4234283c 789\r
421ccda3
HC
790 if ReadOnly:\r
791 if not Executable:\r
792 chmod(ToFile, stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH)\r
793 else:\r
794 chmod(ToFile, stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH | stat.S_IEXEC | stat.S_IXGRP | stat.S_IXOTH)\r
795 elif Executable:\r
796 chmod(ToFile, stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH | stat.S_IWUSR | stat.S_IWGRP |\r
797 stat.S_IWOTH | stat.S_IEXEC | stat.S_IXGRP | stat.S_IXOTH)\r
4234283c 798 else:\r
421ccda3 799 chmod(ToFile, stat.S_IRUSR | stat.S_IRGRP | stat.S_IROTH | stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH)\r
4234283c 800 \r
421ccda3 801 Md5Sigature = md5.new(__FileHookOpen__(str(ToFile), 'rb').read())\r
4234283c 802 Md5Sum = Md5Sigature.hexdigest()\r
421ccda3 803\r
4234283c 804 return Md5Sum\r
421ccda3 805\r
4234283c
LG
806## InstallPackageContent method\r
807#\r
808# @param FromPath: FromPath\r
809# @param ToPath: ToPath\r
810# @param Package: Package\r
811# @param ContentZipFile: ContentZipFile\r
812# @param Dep: Dep\r
813# @param WorkspaceDir: WorkspaceDir\r
814# @param ModuleList: ModuleList\r
815#\r
816def InstallPackageContent(FromPath, ToPath, Package, ContentZipFile, Dep,\r
817 WorkspaceDir, ModuleList, ReadOnly = False):\r
818 if Dep:\r
819 pass\r
820 Package.FileList = []\r
821 \r
822 if ToPath.startswith("\\") or ToPath.startswith("/"):\r
823 ToPath = ToPath[1:]\r
824 \r
825 if not IsValidInstallPath(ToPath):\r
826 Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%ToPath) \r
827\r
828 if FromPath.startswith("\\") or FromPath.startswith("/"):\r
829 FromPath = FromPath[1:]\r
830 \r
831 if not IsValidInstallPath(FromPath):\r
832 Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%FromPath) \r
833 \r
834 PackageFullPath = os.path.normpath(os.path.join(WorkspaceDir, ToPath))\r
835 for MiscFile in Package.GetMiscFileList():\r
836 for Item in MiscFile.GetFileList():\r
837 FileName = Item.GetURI()\r
838 if FileName.startswith("\\") or FileName.startswith("/"):\r
839 FileName = FileName[1:]\r
840 \r
841 if not IsValidInstallPath(FileName):\r
842 Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%FileName)\r
843 \r
844 FromFile = os.path.join(FromPath, FileName)\r
845 Executable = Item.GetExecutable()\r
846 ToFile = (os.path.join(PackageFullPath, ConvertPath(FileName)))\r
847 Md5Sum = InstallFile(ContentZipFile, FromFile, ToFile, ReadOnly, Executable)\r
848 if (ToFile, Md5Sum) not in Package.FileList:\r
849 Package.FileList.append((ToFile, Md5Sum))\r
850 PackageIncludeArchList = [] \r
851 for Item in Package.GetPackageIncludeFileList():\r
852 FileName = Item.GetFilePath()\r
853 if FileName.startswith("\\") or FileName.startswith("/"):\r
854 FileName = FileName[1:]\r
855 \r
856 if not IsValidInstallPath(FileName):\r
857 Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%FileName) \r
858 \r
859 FromFile = os.path.join(FromPath, FileName)\r
860 ToFile = os.path.normpath(os.path.join(PackageFullPath, ConvertPath(FileName)))\r
861 RetFile = ContentZipFile.UnpackFile(FromFile, ToFile)\r
862 if RetFile == '':\r
863 #\r
864 # a non-exist path in Zipfile will return '', which means an include directory in our case\r
865 # save the information for later DEC creation usage and also create the directory\r
866 #\r
867 PackageIncludeArchList.append([Item.GetFilePath(), Item.GetSupArchList()])\r
868 CreateDirectory(ToFile)\r
869 continue\r
870 if ReadOnly:\r
421ccda3 871 chmod(ToFile, stat.S_IRUSR|stat.S_IRGRP|stat.S_IROTH)\r
4234283c 872 else:\r
421ccda3
HC
873 chmod(ToFile, stat.S_IRUSR|stat.S_IRGRP|stat.S_IROTH|stat.S_IWUSR|stat.S_IWGRP|stat.S_IWOTH) \r
874 Md5Sigature = md5.new(__FileHookOpen__(str(ToFile), 'rb').read())\r
4234283c
LG
875 Md5Sum = Md5Sigature.hexdigest()\r
876 if (ToFile, Md5Sum) not in Package.FileList:\r
877 Package.FileList.append((ToFile, Md5Sum))\r
878 Package.SetIncludeArchList(PackageIncludeArchList)\r
879 \r
880 for Item in Package.GetStandardIncludeFileList():\r
881 FileName = Item.GetFilePath()\r
882 if FileName.startswith("\\") or FileName.startswith("/"):\r
883 FileName = FileName[1:]\r
884 \r
885 if not IsValidInstallPath(FileName):\r
886 Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%FileName) \r
887 \r
888 FromFile = os.path.join(FromPath, FileName)\r
889 ToFile = os.path.normpath(os.path.join(PackageFullPath, ConvertPath(FileName)))\r
890 Md5Sum = InstallFile(ContentZipFile, FromFile, ToFile, ReadOnly)\r
891 if (ToFile, Md5Sum) not in Package.FileList:\r
892 Package.FileList.append((ToFile, Md5Sum))\r
893\r
894 #\r
895 # Update package\r
896 #\r
897 Package.SetPackagePath(Package.GetPackagePath().replace(FromPath,\r
898 ToPath, 1))\r
899 Package.SetFullPath(os.path.normpath(os.path.join(PackageFullPath,\r
900 ConvertPath(Package.GetName()) + '.dec')))\r
901\r
902 #\r
903 # Install files in module\r
904 #\r
905 Module = None\r
906 ModuleDict = Package.GetModuleDict()\r
d0acc87a
LG
907 for ModuleGuid, ModuleVersion, ModuleName, ModulePath in ModuleDict:\r
908 Module = ModuleDict[ModuleGuid, ModuleVersion, ModuleName, ModulePath]\r
4234283c
LG
909 InstallModuleContent(FromPath, ToPath, ModulePath, Module,\r
910 ContentZipFile, WorkspaceDir, ModuleList, Package, ReadOnly)\r
911\r
912## GetDPFile method\r
913#\r
914# @param ZipFile: A ZipFile\r
915#\r
916def GetDPFile(ZipFile):\r
917 ContentFile = ''\r
918 DescFile = ''\r
919 for FileName in ZipFile.namelist():\r
920 if FileName.endswith('.content'):\r
921 if not ContentFile:\r
922 ContentFile = FileName\r
923 continue\r
924 elif FileName.endswith('.pkg'):\r
925 if not DescFile:\r
926 DescFile = FileName\r
927 continue\r
928 else:\r
929 continue\r
930 \r
931 Logger.Error("PackagingTool", FILE_TYPE_MISMATCH,\r
932 ExtraData=ST.ERR_DIST_FILE_TOOMANY)\r
933 if not DescFile or not ContentFile:\r
934 Logger.Error("PackagingTool", FILE_UNKNOWN_ERROR,\r
935 ExtraData=ST.ERR_DIST_FILE_TOOFEW)\r
936 return DescFile, ContentFile\r
937\r
421ccda3
HC
938## InstallDp method\r
939#\r
940# Install the distribution to current workspace\r
941#\r
942def InstallDp(DistPkg, DpPkgFileName, ContentZipFile, Options, Dep, WorkspaceDir, DataBase):\r
943 #\r
944 # PackageList, ModuleList record the information for the meta-data\r
945 # files that need to be generated later\r
946 #\r
947 PackageList = []\r
948 ModuleList = []\r
949 DistPkg.PackageSurfaceArea = GetPackageList(DistPkg, Dep, WorkspaceDir, Options, \r
950 ContentZipFile, ModuleList, PackageList)\r
951\r
952 DistPkg.ModuleSurfaceArea = GetModuleList(DistPkg, Dep, WorkspaceDir, ContentZipFile, ModuleList)\r
953 \r
954 GenToolMisc(DistPkg, WorkspaceDir, ContentZipFile)\r
955 \r
956 #\r
957 # copy "Distribution File" to directory $(WORKSPACE)/conf/upt\r
958 #\r
959 DistFileName = os.path.split(DpPkgFileName)[1]\r
960 NewDpPkgFileName = BackupDist(DpPkgFileName, DistPkg.Header.GetGuid(), DistPkg.Header.GetVersion(), WorkspaceDir)\r
961\r
962 #\r
963 # update database\r
964 #\r
965 Logger.Quiet(ST.MSG_UPDATE_PACKAGE_DATABASE)\r
966 DataBase.AddDPObject(DistPkg, NewDpPkgFileName, DistFileName, \r
967 DistPkg.Header.RePackage)\r
968\r