2 # Install distribution package.
4 # Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
6 # SPDX-License-Identifier: BSD-2-Clause-Patent
9 Install a distribution package
14 from Core
.FileHook
import __FileHookOpen__
17 from os
import SEEK_SET
18 from os
import SEEK_END
20 from hashlib
import md5
23 from sys
import platform
24 from shutil
import rmtree
25 from shutil
import copyfile
26 from traceback
import format_exc
27 from platform
import python_version
29 from Logger
import StringTable
as ST
30 from Logger
.ToolError
import UNKNOWN_ERROR
31 from Logger
.ToolError
import FILE_UNKNOWN_ERROR
32 from Logger
.ToolError
import OPTION_MISSING
33 from Logger
.ToolError
import UPT_ALREADY_INSTALLED_ERROR
34 from Logger
.ToolError
import FatalError
35 from Logger
.ToolError
import ABORT_ERROR
36 from Logger
.ToolError
import CODE_ERROR
37 from Logger
.ToolError
import FORMAT_INVALID
38 from Logger
.ToolError
import FILE_TYPE_MISMATCH
39 import Logger
.Log
as Logger
41 from Library
.Misc
import Sdict
42 from Library
.Misc
import ConvertPath
43 from Library
.ParserValidate
import IsValidInstallPath
44 from Xml
.XmlParser
import DistributionPackageXml
45 from GenMetaFile
.GenDecFile
import PackageToDec
46 from GenMetaFile
.GenInfFile
import ModuleToInf
47 from Core
.PackageFile
import PackageFile
48 from Core
.PackageFile
import FILE_NOT_FOUND
49 from Core
.PackageFile
import FILE_CHECKSUM_FAILURE
50 from Core
.PackageFile
import CreateDirectory
51 from Core
.DependencyRules
import DependencyRules
52 from Library
import GlobalData
56 # @param WorkspaceDir: Workspace Directory
57 # @param Path: Package Path
58 # @param CustomPath: whether need to customize path at first
60 def InstallNewPackage(WorkspaceDir
, Path
, CustomPath
= False):
61 if os
.path
.isabs(Path
):
62 Logger
.Info(ST
.MSG_RELATIVE_PATH_ONLY
%Path
)
64 Logger
.Info(ST
.MSG_NEW_PKG_PATH
)
66 Path
= ConvertPath(Path
)
67 Path
= os
.path
.normpath(Path
)
68 FullPath
= os
.path
.normpath(os
.path
.join(WorkspaceDir
, Path
))
69 if os
.path
.exists(FullPath
):
70 Logger
.Info(ST
.ERR_DIR_ALREADY_EXIST
%FullPath
)
74 Input
= stdin
.readline()
75 Input
= Input
.replace('\r', '').replace('\n', '')
77 Logger
.Error("InstallPkg", UNKNOWN_ERROR
, ST
.ERR_USER_INTERRUPT
)
78 Input
= Input
.replace('\r', '').replace('\n', '')
79 return InstallNewPackage(WorkspaceDir
, Input
, False)
83 # @param WorkspaceDir: Workspace Directory
84 # @param Path: Standalone Module Path
85 # @param PathList: The already installed standalone module Path list
87 def InstallNewModule(WorkspaceDir
, Path
, PathList
= None):
90 Path
= ConvertPath(Path
)
91 Path
= os
.path
.normpath(Path
)
92 FullPath
= os
.path
.normpath(os
.path
.join(WorkspaceDir
, Path
))
93 if os
.path
.exists(FullPath
) and FullPath
not in PathList
:
94 Logger
.Info(ST
.ERR_DIR_ALREADY_EXIST
%Path
)
95 elif Path
== FullPath
:
96 Logger
.Info(ST
.MSG_RELATIVE_PATH_ONLY
%FullPath
)
100 Input
= stdin
.readline()
101 Input
= Input
.replace('\r', '').replace('\n', '')
103 Logger
.Error("InstallPkg", UNKNOWN_ERROR
, ST
.ERR_USER_INTERRUPT
)
104 Input
= Input
.replace('\r', '').replace('\n', '')
105 return InstallNewModule(WorkspaceDir
, Input
, PathList
)
110 # @param WorkspaceDir: Workspace Direction
113 def InstallNewFile(WorkspaceDir
, File
):
114 FullPath
= os
.path
.normpath(os
.path
.join(WorkspaceDir
, File
))
115 if os
.path
.exists(FullPath
):
116 Logger
.Info(ST
.ERR_FILE_ALREADY_EXIST
%File
)
117 Input
= stdin
.readline()
118 Input
= Input
.replace('\r', '').replace('\n', '')
120 Logger
.Error("InstallPkg", UNKNOWN_ERROR
, ST
.ERR_USER_INTERRUPT
)
121 Input
= Input
.replace('\r', '').replace('\n', '')
122 return InstallNewFile(WorkspaceDir
, Input
)
130 def UnZipDp(WorkspaceDir
, DpPkgFileName
, Index
=1):
131 ContentZipFile
= None
132 Logger
.Quiet(ST
.MSG_UZIP_PARSE_XML
)
133 DistFile
= PackageFile(DpPkgFileName
)
135 DpDescFileName
, ContentFileName
= GetDPFile(DistFile
.GetZipFile())
137 TempDir
= os
.path
.normpath(os
.path
.join(WorkspaceDir
, "Conf/.tmp%s" % str(Index
)))
138 GlobalData
.gUNPACK_DIR
.append(TempDir
)
139 DistPkgFile
= DistFile
.UnpackFile(DpDescFileName
, os
.path
.normpath(os
.path
.join(TempDir
, DpDescFileName
)))
141 Logger
.Error("InstallPkg", FILE_NOT_FOUND
, ST
.ERR_FILE_BROKEN
%DpDescFileName
)
146 DistPkgObj
= DistributionPackageXml()
147 DistPkg
= DistPkgObj
.FromXml(DistPkgFile
)
148 if DistPkg
.Header
.RePackage
== '':
149 DistPkg
.Header
.RePackage
= False
150 if DistPkg
.Header
.ReadOnly
== '':
151 DistPkg
.Header
.ReadOnly
= False
154 # unzip contents.zip file
156 ContentFile
= DistFile
.UnpackFile(ContentFileName
, os
.path
.normpath(os
.path
.join(TempDir
, ContentFileName
)))
158 Logger
.Error("InstallPkg", FILE_NOT_FOUND
,
159 ST
.ERR_FILE_BROKEN
% ContentFileName
)
164 FileSize
= os
.path
.getsize(ContentFile
)
167 ContentZipFile
= PackageFile(ContentFile
)
170 # verify MD5 signature when existed
172 if DistPkg
.Header
.Signature
!= '':
173 Md5Signature
= md5(__FileHookOpen__(ContentFile
, 'rb').read())
174 if DistPkg
.Header
.Signature
!= Md5Signature
.hexdigest():
175 ContentZipFile
.Close()
176 Logger
.Error("InstallPkg", FILE_CHECKSUM_FAILURE
,
177 ExtraData
=ContentFile
)
179 return DistPkg
, ContentZipFile
, DpPkgFileName
, DistFile
185 def GetPackageList(DistPkg
, Dep
, WorkspaceDir
, Options
, ContentZipFile
, ModuleList
, PackageList
):
187 for Guid
, Version
, Path
in DistPkg
.PackageSurfaceArea
:
189 Package
= DistPkg
.PackageSurfaceArea
[Guid
, Version
, Path
]
190 Logger
.Info(ST
.MSG_INSTALL_PACKAGE
% Package
.GetName())
191 # if Dep.CheckPackageExists(Guid, Version):
192 # Logger.Info(ST.WRN_PACKAGE_EXISTED %(Guid, Version))
193 if Options
.UseGuidedPkgPath
:
194 GuidedPkgPath
= "%s_%s_%s" % (Package
.GetName(), Guid
, Version
)
195 NewPackagePath
= InstallNewPackage(WorkspaceDir
, GuidedPkgPath
, Options
.CustomPath
)
197 NewPackagePath
= InstallNewPackage(WorkspaceDir
, PackagePath
, Options
.CustomPath
)
198 InstallPackageContent(PackagePath
, NewPackagePath
, Package
, ContentZipFile
, Dep
, WorkspaceDir
, ModuleList
,
199 DistPkg
.Header
.ReadOnly
)
200 PackageList
.append(Package
)
202 NewDict
[Guid
, Version
, Package
.GetPackagePath()] = Package
205 # Now generate meta-data files, first generate all dec for package
206 # dec should be generated before inf, and inf should be generated after
207 # all packages installed, else hard to resolve modules' package
208 # dependency (Hard to get the location of the newly installed package)
210 for Package
in PackageList
:
211 FilePath
= PackageToDec(Package
, DistPkg
.Header
)
212 Md5Signature
= md5(__FileHookOpen__(str(FilePath
), 'rb').read())
213 Md5Sum
= Md5Signature
.hexdigest()
214 if (FilePath
, Md5Sum
) not in Package
.FileList
:
215 Package
.FileList
.append((FilePath
, Md5Sum
))
223 def GetModuleList(DistPkg
, Dep
, WorkspaceDir
, ContentZipFile
, ModuleList
):
225 # ModulePathList will keep track of the standalone module path that
226 # we just installed. If a new module's path in that list
227 # (only multiple INF in one directory will be so), we will
228 # install them directly. If not, we will try to create a new directory
234 # Check module exist and install
238 for Guid
, Version
, Name
, Path
in DistPkg
.ModuleSurfaceArea
:
240 Module
= DistPkg
.ModuleSurfaceArea
[Guid
, Version
, Name
, Path
]
241 Logger
.Info(ST
.MSG_INSTALL_MODULE
% Module
.GetName())
242 if Dep
.CheckModuleExists(Guid
, Version
, Name
, Path
):
243 Logger
.Quiet(ST
.WRN_MODULE_EXISTED
%Path
)
245 # here check for the multiple inf share the same module path cases:
246 # they should be installed into the same directory
249 os
.path
.normpath(os
.path
.join(WorkspaceDir
, ModulePath
))
250 if ModuleFullPath
not in ModulePathList
:
251 NewModulePath
= InstallNewModule(WorkspaceDir
, ModulePath
, ModulePathList
)
252 NewModuleFullPath
= os
.path
.normpath(os
.path
.join(WorkspaceDir
, NewModulePath
))
253 ModulePathList
.append(NewModuleFullPath
)
255 NewModulePath
= ModulePath
257 InstallModuleContent(ModulePath
, NewModulePath
, '', Module
, ContentZipFile
, WorkspaceDir
, ModuleList
, None,
258 DistPkg
.Header
.ReadOnly
)
262 Module
.SetModulePath(Module
.GetModulePath().replace(Path
, NewModulePath
, 1))
264 NewDict
[Guid
, Version
, Name
, Module
.GetModulePath()] = Module
267 # generate all inf for modules
269 for (Module
, Package
) in ModuleList
:
270 CheckCNameInModuleRedefined(Module
, DistPkg
)
271 FilePath
= ModuleToInf(Module
, Package
, DistPkg
.Header
)
272 Md5Signature
= md5(__FileHookOpen__(str(FilePath
), 'rb').read())
273 Md5Sum
= Md5Signature
.hexdigest()
275 if (FilePath
, Md5Sum
) not in Package
.FileList
:
276 Package
.FileList
.append((FilePath
, Md5Sum
))
278 if (FilePath
, Md5Sum
) not in Module
.FileList
:
279 Module
.FileList
.append((FilePath
, Md5Sum
))
281 # append the module unicode files to Package FileList
283 for (FilePath
, Md5Sum
) in Module
.FileList
:
284 if str(FilePath
).endswith('.uni') and Package
and (FilePath
, Md5Sum
) not in Package
.FileList
:
285 Package
.FileList
.append((FilePath
, Md5Sum
))
290 # Get all protocol/ppi/guid CNames and pcd name from all dependent DEC file
292 def GetDepProtocolPpiGuidPcdNames(DePackageObjList
):
294 # [[Dec1Protocol1, Dec1Protocol2...], [Dec2Protocols...],...]
296 DependentProtocolCNames
= []
297 DependentPpiCNames
= []
298 DependentGuidCNames
= []
299 DependentPcdNames
= []
301 for PackageObj
in DePackageObjList
:
303 # Get protocol CName list from all dependent DEC file
306 for Protocol
in PackageObj
.GetProtocolList():
307 if Protocol
.GetCName() not in ProtocolCNames
:
308 ProtocolCNames
.append(Protocol
.GetCName())
310 DependentProtocolCNames
.append(ProtocolCNames
)
313 # Get Ppi CName list from all dependent DEC file
316 for Ppi
in PackageObj
.GetPpiList():
317 if Ppi
.GetCName() not in PpiCNames
:
318 PpiCNames
.append(Ppi
.GetCName())
320 DependentPpiCNames
.append(PpiCNames
)
323 # Get Guid CName list from all dependent DEC file
326 for Guid
in PackageObj
.GetGuidList():
327 if Guid
.GetCName() not in GuidCNames
:
328 GuidCNames
.append(Guid
.GetCName())
330 DependentGuidCNames
.append(GuidCNames
)
333 # Get PcdName list from all dependent DEC file
336 for Pcd
in PackageObj
.GetPcdList():
337 PcdName
= '.'.join([Pcd
.GetTokenSpaceGuidCName(), Pcd
.GetCName()])
338 if PcdName
not in PcdNames
:
339 PcdNames
.append(PcdName
)
341 DependentPcdNames
.append(PcdNames
)
344 return DependentProtocolCNames
, DependentPpiCNames
, DependentGuidCNames
, DependentPcdNames
347 # Check if protocol CName is redefined
349 def CheckProtoclCNameRedefined(Module
, DependentProtocolCNames
):
350 for ProtocolInModule
in Module
.GetProtocolList():
351 IsCNameDefined
= False
352 for PackageProtocolCNames
in DependentProtocolCNames
:
353 if ProtocolInModule
.GetCName() in PackageProtocolCNames
:
355 Logger
.Error("\nUPT", FORMAT_INVALID
,
356 File
= Module
.GetFullPath(),
358 ST
.ERR_INF_PARSER_ITEM_DUPLICATE_IN_DEC
% ProtocolInModule
.GetCName())
360 IsCNameDefined
= True
363 # Check if Ppi CName is redefined
365 def CheckPpiCNameRedefined(Module
, DependentPpiCNames
):
366 for PpiInModule
in Module
.GetPpiList():
367 IsCNameDefined
= False
368 for PackagePpiCNames
in DependentPpiCNames
:
369 if PpiInModule
.GetCName() in PackagePpiCNames
:
371 Logger
.Error("\nUPT", FORMAT_INVALID
,
372 File
= Module
.GetFullPath(),
373 ExtraData
= ST
.ERR_INF_PARSER_ITEM_DUPLICATE_IN_DEC
% PpiInModule
.GetCName())
375 IsCNameDefined
= True
378 # Check if Guid CName is redefined
380 def CheckGuidCNameRedefined(Module
, DependentGuidCNames
):
381 for GuidInModule
in Module
.GetGuidList():
382 IsCNameDefined
= False
383 for PackageGuidCNames
in DependentGuidCNames
:
384 if GuidInModule
.GetCName() in PackageGuidCNames
:
386 Logger
.Error("\nUPT", FORMAT_INVALID
,
387 File
= Module
.GetFullPath(),
389 ST
.ERR_INF_PARSER_ITEM_DUPLICATE_IN_DEC
% GuidInModule
.GetCName())
391 IsCNameDefined
= True
394 # Check if PcdName is redefined
396 def CheckPcdNameRedefined(Module
, DependentPcdNames
):
398 if not Module
.GetBinaryFileList():
399 PcdObjs
+= Module
.GetPcdList()
401 Binary
= Module
.GetBinaryFileList()[0]
402 for AsBuild
in Binary
.GetAsBuiltList():
403 PcdObjs
+= AsBuild
.GetPatchPcdList() + AsBuild
.GetPcdExList()
405 for PcdObj
in PcdObjs
:
406 PcdName
= '.'.join([PcdObj
.GetTokenSpaceGuidCName(), PcdObj
.GetCName()])
407 IsPcdNameDefined
= False
408 for PcdNames
in DependentPcdNames
:
409 if PcdName
in PcdNames
:
411 Logger
.Error("\nUPT", FORMAT_INVALID
,
412 File
= Module
.GetFullPath(),
413 ExtraData
= ST
.ERR_INF_PARSER_ITEM_DUPLICATE_IN_DEC
% PcdName
)
415 IsPcdNameDefined
= True
418 # Check if any Protocol/Ppi/Guid and Pcd name is redefined in its dependent DEC files
420 def CheckCNameInModuleRedefined(Module
, DistPkg
):
421 DePackageObjList
= []
423 # Get all dependent package objects
425 for Obj
in Module
.GetPackageDependencyList():
427 Version
= Obj
.GetVersion()
428 for Key
in DistPkg
.PackageSurfaceArea
:
429 if Key
[0] == Guid
and Key
[1] == Version
:
430 if DistPkg
.PackageSurfaceArea
[Key
] not in DePackageObjList
:
431 DePackageObjList
.append(DistPkg
.PackageSurfaceArea
[Key
])
433 DependentProtocolCNames
, DependentPpiCNames
, DependentGuidCNames
, DependentPcdNames
= \
434 GetDepProtocolPpiGuidPcdNames(DePackageObjList
)
436 CheckProtoclCNameRedefined(Module
, DependentProtocolCNames
)
437 CheckPpiCNameRedefined(Module
, DependentPpiCNames
)
438 CheckGuidCNameRedefined(Module
, DependentGuidCNames
)
439 CheckPcdNameRedefined(Module
, DependentPcdNames
)
446 def GenToolMisc(DistPkg
, WorkspaceDir
, ContentZipFile
):
447 ToolObject
= DistPkg
.Tools
448 MiscObject
= DistPkg
.MiscellaneousFiles
449 DistPkg
.FileList
= []
453 RootDir
= WorkspaceDir
456 # FileList stores both tools files and misc files
457 # Misc file list must be appended to FileList *AFTER* Tools file list
460 FileList
+= ToolObject
.GetFileList()
461 ToolFileNum
= len(ToolObject
.GetFileList())
462 if 'EDK_TOOLS_PATH' in os
.environ
:
463 RootDir
= os
.environ
['EDK_TOOLS_PATH']
465 FileList
+= MiscObject
.GetFileList()
466 for FileObject
in FileList
:
468 if FileNum
> ToolFileNum
:
470 # Misc files, root should be changed to WORKSPACE
472 RootDir
= WorkspaceDir
473 File
= ConvertPath(FileObject
.GetURI())
474 ToFile
= os
.path
.normpath(os
.path
.join(RootDir
, File
))
475 if os
.path
.exists(ToFile
):
476 Logger
.Info( ST
.WRN_FILE_EXISTED
% ToFile
)
478 # ask for user input the new file name
480 Logger
.Info( ST
.MSG_NEW_FILE_NAME
)
481 Input
= stdin
.readline()
482 Input
= Input
.replace('\r', '').replace('\n', '')
483 OrigPath
= os
.path
.split(ToFile
)[0]
484 ToFile
= os
.path
.normpath(os
.path
.join(OrigPath
, Input
))
485 FromFile
= os
.path
.join(FileObject
.GetURI())
486 Md5Sum
= InstallFile(ContentZipFile
, FromFile
, ToFile
, DistPkg
.Header
.ReadOnly
, FileObject
.GetExecutable())
487 DistPkg
.FileList
.append((ToFile
, Md5Sum
))
489 ## Tool entrance method
491 # This method mainly dispatch specific methods per the command line options.
492 # If no error found, return zero value so the caller of this tool can know
493 # if it's executed successfully or not.
495 # @param Options: command Options
497 def Main(Options
= None):
499 DataBase
= GlobalData
.gDB
500 WorkspaceDir
= GlobalData
.gWORKSPACE
501 if not Options
.PackageFile
:
502 Logger
.Error("InstallPkg", OPTION_MISSING
, ExtraData
=ST
.ERR_SPECIFY_PACKAGE
)
508 for ToBeInstalledDist
in Options
.PackageFile
:
510 # unzip dist.pkg file
512 DistInfoList
.append(UnZipDp(WorkspaceDir
, ToBeInstalledDist
, Index
))
513 DistPkgList
.append(DistInfoList
[-1][0])
519 GlobalData
.gTO_BE_INSTALLED_DIST_LIST
.append(DistInfoList
[-1][0])
521 # Check for dependency
522 Dep
= DependencyRules(DataBase
, DistPkgList
)
524 for ToBeInstalledDist
in DistInfoList
:
525 CheckInstallDpx(Dep
, ToBeInstalledDist
[0], ToBeInstalledDist
[2])
528 # Install distribution
530 InstallDp(ToBeInstalledDist
[0], ToBeInstalledDist
[2], ToBeInstalledDist
[1],
531 Options
, Dep
, WorkspaceDir
, DataBase
)
534 except FatalError
as XExcept
:
535 ReturnCode
= XExcept
.args
[0]
536 if Logger
.GetLevel() <= Logger
.DEBUG_9
:
537 Logger
.Quiet(ST
.MSG_PYTHON_ON
% (python_version(), platform
) + format_exc())
539 except KeyboardInterrupt:
540 ReturnCode
= ABORT_ERROR
541 if Logger
.GetLevel() <= Logger
.DEBUG_9
:
542 Logger
.Quiet(ST
.MSG_PYTHON_ON
% (python_version(), platform
) + format_exc())
545 ReturnCode
= CODE_ERROR
549 ST
.ERR_UNKNOWN_FATAL_INSTALL_ERR
% Options
.PackageFile
,
550 ExtraData
=ST
.MSG_SEARCH_FOR_HELP
,
553 Logger
.Quiet(ST
.MSG_PYTHON_ON
% (python_version(),
554 platform
) + format_exc())
556 Logger
.Quiet(ST
.MSG_REMOVE_TEMP_FILE_STARTED
)
557 for ToBeInstalledDist
in DistInfoList
:
558 if ToBeInstalledDist
[3]:
559 ToBeInstalledDist
[3].Close()
560 if ToBeInstalledDist
[1]:
561 ToBeInstalledDist
[1].Close()
562 for TempDir
in GlobalData
.gUNPACK_DIR
:
564 GlobalData
.gUNPACK_DIR
= []
565 Logger
.Quiet(ST
.MSG_REMOVE_TEMP_FILE_DONE
)
567 Logger
.Quiet(ST
.MSG_FINISH
)
572 # This method will backup the Distribution file into the $(WORKSPACE)/conf/upt, and rename it
573 # if there is already a same-named distribution existed.
575 # @param DpPkgFileName: The distribution path
576 # @param Guid: The distribution Guid
577 # @param Version: The distribution Version
578 # @param WorkspaceDir: The workspace directory
579 # @retval NewDpPkgFileName: The exact backup file name
581 def BackupDist(DpPkgFileName
, Guid
, Version
, WorkspaceDir
):
582 DistFileName
= os
.path
.split(DpPkgFileName
)[1]
583 DestDir
= os
.path
.normpath(os
.path
.join(WorkspaceDir
, GlobalData
.gUPT_DIR
))
584 CreateDirectory(DestDir
)
585 DestFile
= os
.path
.normpath(os
.path
.join(DestDir
, DistFileName
))
586 if os
.path
.exists(DestFile
):
587 FileName
, Ext
= os
.path
.splitext(DistFileName
)
588 NewFileName
= FileName
+ '_' + Guid
+ '_' + Version
+ Ext
589 DestFile
= os
.path
.normpath(os
.path
.join(DestDir
, NewFileName
))
590 if os
.path
.exists(DestFile
):
592 # ask for user input the new file name
594 Logger
.Info( ST
.MSG_NEW_FILE_NAME_FOR_DIST
)
595 Input
= stdin
.readline()
596 Input
= Input
.replace('\r', '').replace('\n', '')
597 DestFile
= os
.path
.normpath(os
.path
.join(DestDir
, Input
))
598 copyfile(DpPkgFileName
, DestFile
)
599 NewDpPkgFileName
= DestFile
[DestFile
.find(DestDir
) + len(DestDir
) + 1:]
600 return NewDpPkgFileName
602 ## CheckInstallDpx method
604 # check whether distribution could be installed
606 # @param Dep: the DependencyRules instance that used to check dependency
607 # @param DistPkg: the distribution object
609 def CheckInstallDpx(Dep
, DistPkg
, DistPkgFileName
):
611 # Check distribution package installed or not
613 if Dep
.CheckDpExists(DistPkg
.Header
.GetGuid(),
614 DistPkg
.Header
.GetVersion()):
615 Logger
.Error("InstallPkg",
616 UPT_ALREADY_INSTALLED_ERROR
,
617 ST
.WRN_DIST_PKG_INSTALLED
% os
.path
.basename(DistPkgFileName
))
619 # Check distribution dependency (all module dependency should be
622 if not Dep
.CheckInstallDpDepexSatisfied(DistPkg
):
623 Logger
.Error("InstallPkg", UNKNOWN_ERROR
,
624 ST
.ERR_PACKAGE_NOT_MATCH_DEPENDENCY
,
625 ExtraData
=DistPkg
.Header
.Name
)
627 ## InstallModuleContent method
629 # If this is standalone module, then Package should be none,
630 # ModulePath should be ''
631 # @param FromPath: FromPath
632 # @param NewPath: NewPath
633 # @param ModulePath: ModulePath
634 # @param Module: Module
635 # @param ContentZipFile: ContentZipFile
636 # @param WorkspaceDir: WorkspaceDir
637 # @param ModuleList: ModuleList
638 # @param Package: Package
640 def InstallModuleContent(FromPath
, NewPath
, ModulePath
, Module
, ContentZipFile
,
641 WorkspaceDir
, ModuleList
, Package
= None, ReadOnly
= False):
643 if NewPath
.startswith("\\") or NewPath
.startswith("/"):
644 NewPath
= NewPath
[1:]
646 if not IsValidInstallPath(NewPath
):
647 Logger
.Error("UPT", FORMAT_INVALID
, ST
.ERR_FILE_NAME_INVALIDE
%NewPath
)
649 NewModuleFullPath
= os
.path
.normpath(os
.path
.join(WorkspaceDir
, NewPath
,
650 ConvertPath(ModulePath
)))
651 Module
.SetFullPath(os
.path
.normpath(os
.path
.join(NewModuleFullPath
,
652 ConvertPath(Module
.GetName()) + '.inf')))
655 for MiscFile
in Module
.GetMiscFileList():
658 for Item
in MiscFile
.GetFileList():
660 if File
.startswith("\\") or File
.startswith("/"):
663 if not IsValidInstallPath(File
):
664 Logger
.Error("UPT", FORMAT_INVALID
, ST
.ERR_FILE_NAME_INVALIDE
%File
)
666 FromFile
= os
.path
.join(FromPath
, ModulePath
, File
)
667 Executable
= Item
.GetExecutable()
668 ToFile
= os
.path
.normpath(os
.path
.join(NewModuleFullPath
, ConvertPath(File
)))
669 Md5Sum
= InstallFile(ContentZipFile
, FromFile
, ToFile
, ReadOnly
, Executable
)
670 if Package
and ((ToFile
, Md5Sum
) not in Package
.FileList
):
671 Package
.FileList
.append((ToFile
, Md5Sum
))
674 elif (ToFile
, Md5Sum
) not in Module
.FileList
:
675 Module
.FileList
.append((ToFile
, Md5Sum
))
676 for Item
in Module
.GetSourceFileList():
677 File
= Item
.GetSourceFile()
678 if File
.startswith("\\") or File
.startswith("/"):
681 if not IsValidInstallPath(File
):
682 Logger
.Error("UPT", FORMAT_INVALID
, ST
.ERR_FILE_NAME_INVALIDE
%File
)
684 FromFile
= os
.path
.join(FromPath
, ModulePath
, File
)
685 ToFile
= os
.path
.normpath(os
.path
.join(NewModuleFullPath
, ConvertPath(File
)))
686 Md5Sum
= InstallFile(ContentZipFile
, FromFile
, ToFile
, ReadOnly
)
687 if Package
and ((ToFile
, Md5Sum
) not in Package
.FileList
):
688 Package
.FileList
.append((ToFile
, Md5Sum
))
691 elif (ToFile
, Md5Sum
) not in Module
.FileList
:
692 Module
.FileList
.append((ToFile
, Md5Sum
))
693 for Item
in Module
.GetBinaryFileList():
694 FileNameList
= Item
.GetFileNameList()
695 for FileName
in FileNameList
:
696 File
= FileName
.GetFilename()
697 if File
.startswith("\\") or File
.startswith("/"):
700 if not IsValidInstallPath(File
):
701 Logger
.Error("UPT", FORMAT_INVALID
, ST
.ERR_FILE_NAME_INVALIDE
%File
)
703 FromFile
= os
.path
.join(FromPath
, ModulePath
, File
)
704 ToFile
= os
.path
.normpath(os
.path
.join(NewModuleFullPath
, ConvertPath(File
)))
705 Md5Sum
= InstallFile(ContentZipFile
, FromFile
, ToFile
, ReadOnly
)
706 if Package
and ((ToFile
, Md5Sum
) not in Package
.FileList
):
707 Package
.FileList
.append((ToFile
, Md5Sum
))
710 elif (ToFile
, Md5Sum
) not in Module
.FileList
:
711 Module
.FileList
.append((ToFile
, Md5Sum
))
713 InstallModuleContentZipFile(ContentZipFile
, FromPath
, ModulePath
, WorkspaceDir
, NewPath
, Module
, Package
, ReadOnly
,
716 ## InstallModuleContentZipFile
718 # InstallModuleContentZipFile
720 def InstallModuleContentZipFile(ContentZipFile
, FromPath
, ModulePath
, WorkspaceDir
, NewPath
, Module
, Package
, ReadOnly
,
723 # Extract other files under current module path in content Zip file but not listed in the description
726 for FileName
in ContentZipFile
.GetZipFile().namelist():
727 FileName
= os
.path
.normpath(FileName
)
728 CheckPath
= os
.path
.normpath(os
.path
.join(FromPath
, ModulePath
))
729 if FileUnderPath(FileName
, CheckPath
):
730 if FileName
.startswith("\\") or FileName
.startswith("/"):
731 FileName
= FileName
[1:]
733 if not IsValidInstallPath(FileName
):
734 Logger
.Error("UPT", FORMAT_INVALID
, ST
.ERR_FILE_NAME_INVALIDE
%FileName
)
737 ToFile
= os
.path
.normpath(os
.path
.join(WorkspaceDir
,
738 ConvertPath(FileName
.replace(FromPath
, NewPath
, 1))))
739 CheckList
= copy
.copy(Module
.FileList
)
741 CheckList
+= Package
.FileList
742 for Item
in CheckList
:
743 if Item
[0] == ToFile
:
746 Md5Sum
= InstallFile(ContentZipFile
, FromFile
, ToFile
, ReadOnly
)
747 if Package
and ((ToFile
, Md5Sum
) not in Package
.FileList
):
748 Package
.FileList
.append((ToFile
, Md5Sum
))
751 elif (ToFile
, Md5Sum
) not in Module
.FileList
:
752 Module
.FileList
.append((ToFile
, Md5Sum
))
754 ModuleList
.append((Module
, Package
))
757 # Check whether FileName started with directory specified by CheckPath
759 # @param FileName: the FileName need to be checked
760 # @param CheckPath: the path need to be checked against
761 # @return: True or False
763 def FileUnderPath(FileName
, CheckPath
):
764 FileName
= FileName
.replace('\\', '/')
765 FileName
= os
.path
.normpath(FileName
)
766 CheckPath
= CheckPath
.replace('\\', '/')
767 CheckPath
= os
.path
.normpath(CheckPath
)
768 if FileName
.startswith(CheckPath
):
769 RemainingPath
= os
.path
.normpath(FileName
.replace(CheckPath
, '', 1))
770 while RemainingPath
.startswith('\\') or RemainingPath
.startswith('/'):
771 RemainingPath
= RemainingPath
[1:]
772 if FileName
== os
.path
.normpath(os
.path
.join(CheckPath
, RemainingPath
)):
778 # Extract File from Zipfile, set file attribute, and return the Md5Sum
780 # @return: True or False
782 def InstallFile(ContentZipFile
, FromFile
, ToFile
, ReadOnly
, Executable
=False):
783 if os
.path
.exists(os
.path
.normpath(ToFile
)):
786 if not ContentZipFile
or not ContentZipFile
.UnpackFile(FromFile
, ToFile
):
787 Logger
.Error("UPT", FILE_NOT_FOUND
, ST
.ERR_INSTALL_FILE_FROM_EMPTY_CONTENT
% FromFile
)
791 chmod(ToFile
, stat
.S_IRUSR | stat
.S_IRGRP | stat
.S_IROTH
)
793 chmod(ToFile
, stat
.S_IRUSR | stat
.S_IRGRP | stat
.S_IROTH | stat
.S_IEXEC | stat
.S_IXGRP | stat
.S_IXOTH
)
795 chmod(ToFile
, stat
.S_IRUSR | stat
.S_IRGRP | stat
.S_IROTH | stat
.S_IWUSR | stat
.S_IWGRP |
796 stat
.S_IWOTH | stat
.S_IEXEC | stat
.S_IXGRP | stat
.S_IXOTH
)
798 chmod(ToFile
, stat
.S_IRUSR | stat
.S_IRGRP | stat
.S_IROTH | stat
.S_IWUSR | stat
.S_IWGRP | stat
.S_IWOTH
)
800 Md5Signature
= md5(__FileHookOpen__(str(ToFile
), 'rb').read())
801 Md5Sum
= Md5Signature
.hexdigest()
805 ## InstallPackageContent method
807 # @param FromPath: FromPath
808 # @param ToPath: ToPath
809 # @param Package: Package
810 # @param ContentZipFile: ContentZipFile
812 # @param WorkspaceDir: WorkspaceDir
813 # @param ModuleList: ModuleList
815 def InstallPackageContent(FromPath
, ToPath
, Package
, ContentZipFile
, Dep
,
816 WorkspaceDir
, ModuleList
, ReadOnly
= False):
819 Package
.FileList
= []
821 if ToPath
.startswith("\\") or ToPath
.startswith("/"):
824 if not IsValidInstallPath(ToPath
):
825 Logger
.Error("UPT", FORMAT_INVALID
, ST
.ERR_FILE_NAME_INVALIDE
%ToPath
)
827 if FromPath
.startswith("\\") or FromPath
.startswith("/"):
828 FromPath
= FromPath
[1:]
830 if not IsValidInstallPath(FromPath
):
831 Logger
.Error("UPT", FORMAT_INVALID
, ST
.ERR_FILE_NAME_INVALIDE
%FromPath
)
833 PackageFullPath
= os
.path
.normpath(os
.path
.join(WorkspaceDir
, ToPath
))
834 for MiscFile
in Package
.GetMiscFileList():
835 for Item
in MiscFile
.GetFileList():
836 FileName
= Item
.GetURI()
837 if FileName
.startswith("\\") or FileName
.startswith("/"):
838 FileName
= FileName
[1:]
840 if not IsValidInstallPath(FileName
):
841 Logger
.Error("UPT", FORMAT_INVALID
, ST
.ERR_FILE_NAME_INVALIDE
%FileName
)
843 FromFile
= os
.path
.join(FromPath
, FileName
)
844 Executable
= Item
.GetExecutable()
845 ToFile
= (os
.path
.join(PackageFullPath
, ConvertPath(FileName
)))
846 Md5Sum
= InstallFile(ContentZipFile
, FromFile
, ToFile
, ReadOnly
, Executable
)
847 if (ToFile
, Md5Sum
) not in Package
.FileList
:
848 Package
.FileList
.append((ToFile
, Md5Sum
))
849 PackageIncludeArchList
= []
850 for Item
in Package
.GetPackageIncludeFileList():
851 FileName
= Item
.GetFilePath()
852 if FileName
.startswith("\\") or FileName
.startswith("/"):
853 FileName
= FileName
[1:]
855 if not IsValidInstallPath(FileName
):
856 Logger
.Error("UPT", FORMAT_INVALID
, ST
.ERR_FILE_NAME_INVALIDE
%FileName
)
858 FromFile
= os
.path
.join(FromPath
, FileName
)
859 ToFile
= os
.path
.normpath(os
.path
.join(PackageFullPath
, ConvertPath(FileName
)))
860 RetFile
= ContentZipFile
.UnpackFile(FromFile
, ToFile
)
863 # a non-exist path in Zipfile will return '', which means an include directory in our case
864 # save the information for later DEC creation usage and also create the directory
866 PackageIncludeArchList
.append([Item
.GetFilePath(), Item
.GetSupArchList()])
867 CreateDirectory(ToFile
)
870 chmod(ToFile
, stat
.S_IRUSR|stat
.S_IRGRP|stat
.S_IROTH
)
872 chmod(ToFile
, stat
.S_IRUSR|stat
.S_IRGRP|stat
.S_IROTH|stat
.S_IWUSR|stat
.S_IWGRP|stat
.S_IWOTH
)
873 Md5Signature
= md5(__FileHookOpen__(str(ToFile
), 'rb').read())
874 Md5Sum
= Md5Signature
.hexdigest()
875 if (ToFile
, Md5Sum
) not in Package
.FileList
:
876 Package
.FileList
.append((ToFile
, Md5Sum
))
877 Package
.SetIncludeArchList(PackageIncludeArchList
)
879 for Item
in Package
.GetStandardIncludeFileList():
880 FileName
= Item
.GetFilePath()
881 if FileName
.startswith("\\") or FileName
.startswith("/"):
882 FileName
= FileName
[1:]
884 if not IsValidInstallPath(FileName
):
885 Logger
.Error("UPT", FORMAT_INVALID
, ST
.ERR_FILE_NAME_INVALIDE
%FileName
)
887 FromFile
= os
.path
.join(FromPath
, FileName
)
888 ToFile
= os
.path
.normpath(os
.path
.join(PackageFullPath
, ConvertPath(FileName
)))
889 Md5Sum
= InstallFile(ContentZipFile
, FromFile
, ToFile
, ReadOnly
)
890 if (ToFile
, Md5Sum
) not in Package
.FileList
:
891 Package
.FileList
.append((ToFile
, Md5Sum
))
896 Package
.SetPackagePath(Package
.GetPackagePath().replace(FromPath
,
898 Package
.SetFullPath(os
.path
.normpath(os
.path
.join(PackageFullPath
,
899 ConvertPath(Package
.GetName()) + '.dec')))
902 # Install files in module
905 ModuleDict
= Package
.GetModuleDict()
906 for ModuleGuid
, ModuleVersion
, ModuleName
, ModulePath
in ModuleDict
:
907 Module
= ModuleDict
[ModuleGuid
, ModuleVersion
, ModuleName
, ModulePath
]
908 InstallModuleContent(FromPath
, ToPath
, ModulePath
, Module
,
909 ContentZipFile
, WorkspaceDir
, ModuleList
, Package
, ReadOnly
)
913 # @param ZipFile: A ZipFile
915 def GetDPFile(ZipFile
):
918 for FileName
in ZipFile
.namelist():
919 if FileName
.endswith('.content'):
921 ContentFile
= FileName
923 elif FileName
.endswith('.pkg'):
930 Logger
.Error("PackagingTool", FILE_TYPE_MISMATCH
,
931 ExtraData
=ST
.ERR_DIST_FILE_TOOMANY
)
932 if not DescFile
or not ContentFile
:
933 Logger
.Error("PackagingTool", FILE_UNKNOWN_ERROR
,
934 ExtraData
=ST
.ERR_DIST_FILE_TOOFEW
)
935 return DescFile
, ContentFile
939 # Install the distribution to current workspace
941 def InstallDp(DistPkg
, DpPkgFileName
, ContentZipFile
, Options
, Dep
, WorkspaceDir
, DataBase
):
943 # PackageList, ModuleList record the information for the meta-data
944 # files that need to be generated later
948 DistPkg
.PackageSurfaceArea
= GetPackageList(DistPkg
, Dep
, WorkspaceDir
, Options
,
949 ContentZipFile
, ModuleList
, PackageList
)
951 DistPkg
.ModuleSurfaceArea
= GetModuleList(DistPkg
, Dep
, WorkspaceDir
, ContentZipFile
, ModuleList
)
953 GenToolMisc(DistPkg
, WorkspaceDir
, ContentZipFile
)
956 # copy "Distribution File" to directory $(WORKSPACE)/conf/upt
958 DistFileName
= os
.path
.split(DpPkgFileName
)[1]
959 NewDpPkgFileName
= BackupDist(DpPkgFileName
, DistPkg
.Header
.GetGuid(), DistPkg
.Header
.GetVersion(), WorkspaceDir
)
964 Logger
.Quiet(ST
.MSG_UPDATE_PACKAGE_DATABASE
)
965 DataBase
.AddDPObject(DistPkg
, NewDpPkgFileName
, DistFileName
,
966 DistPkg
.Header
.RePackage
)