2 # Install distribution package.
4 # Copyright (c) 2011 - 2015, 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.
15 Install a distribution package
20 from Core
.FileHook
import __FileHookOpen__
23 from os
import SEEK_SET
24 from os
import SEEK_END
29 from sys
import platform
30 from shutil
import rmtree
31 from shutil
import copyfile
32 from traceback
import format_exc
33 from platform
import python_version
35 from Logger
import StringTable
as ST
36 from Logger
.ToolError
import UNKNOWN_ERROR
37 from Logger
.ToolError
import FILE_UNKNOWN_ERROR
38 from Logger
.ToolError
import OPTION_MISSING
39 from Logger
.ToolError
import UPT_ALREADY_INSTALLED_ERROR
40 from Logger
.ToolError
import FatalError
41 from Logger
.ToolError
import ABORT_ERROR
42 from Logger
.ToolError
import CODE_ERROR
43 from Logger
.ToolError
import FORMAT_INVALID
44 from Logger
.ToolError
import FILE_TYPE_MISMATCH
45 import Logger
.Log
as Logger
47 from Library
.Misc
import Sdict
48 from Library
.Misc
import ConvertPath
49 from Library
.ParserValidate
import IsValidInstallPath
50 from Xml
.XmlParser
import DistributionPackageXml
51 from GenMetaFile
.GenDecFile
import PackageToDec
52 from GenMetaFile
.GenInfFile
import ModuleToInf
53 from Core
.PackageFile
import PackageFile
54 from Core
.PackageFile
import FILE_NOT_FOUND
55 from Core
.PackageFile
import FILE_CHECKSUM_FAILURE
56 from Core
.PackageFile
import CreateDirectory
57 from Core
.DependencyRules
import DependencyRules
58 from Library
import GlobalData
62 # @param WorkspaceDir: Workspace Directory
63 # @param Path: Package Path
64 # @param CustomPath: whether need to customize path at first
66 def InstallNewPackage(WorkspaceDir
, Path
, CustomPath
= False):
67 if os
.path
.isabs(Path
):
68 Logger
.Info(ST
.MSG_RELATIVE_PATH_ONLY
%Path
)
70 Logger
.Info(ST
.MSG_NEW_PKG_PATH
)
72 Path
= ConvertPath(Path
)
73 Path
= os
.path
.normpath(Path
)
74 FullPath
= os
.path
.normpath(os
.path
.join(WorkspaceDir
, Path
))
75 if os
.path
.exists(FullPath
):
76 Logger
.Info(ST
.ERR_DIR_ALREADY_EXIST
%FullPath
)
80 Input
= stdin
.readline()
81 Input
= Input
.replace('\r', '').replace('\n', '')
83 Logger
.Error("InstallPkg", UNKNOWN_ERROR
, ST
.ERR_USER_INTERRUPT
)
84 Input
= Input
.replace('\r', '').replace('\n', '')
85 return InstallNewPackage(WorkspaceDir
, Input
, False)
89 # @param WorkspaceDir: Workspace Directory
90 # @param Path: Standalone Module Path
91 # @param PathList: The already installed standalone module Path list
93 def InstallNewModule(WorkspaceDir
, Path
, PathList
= None):
96 Path
= ConvertPath(Path
)
97 Path
= os
.path
.normpath(Path
)
98 FullPath
= os
.path
.normpath(os
.path
.join(WorkspaceDir
, Path
))
99 if os
.path
.exists(FullPath
) and FullPath
not in PathList
:
100 Logger
.Info(ST
.ERR_DIR_ALREADY_EXIST
%Path
)
101 elif Path
== FullPath
:
102 Logger
.Info(ST
.MSG_RELATIVE_PATH_ONLY
%FullPath
)
106 Input
= stdin
.readline()
107 Input
= Input
.replace('\r', '').replace('\n', '')
109 Logger
.Error("InstallPkg", UNKNOWN_ERROR
, ST
.ERR_USER_INTERRUPT
)
110 Input
= Input
.replace('\r', '').replace('\n', '')
111 return InstallNewModule(WorkspaceDir
, Input
, PathList
)
116 # @param WorkspaceDir: Workspace Direction
119 def InstallNewFile(WorkspaceDir
, File
):
120 FullPath
= os
.path
.normpath(os
.path
.join(WorkspaceDir
, File
))
121 if os
.path
.exists(FullPath
):
122 Logger
.Info(ST
.ERR_FILE_ALREADY_EXIST
%File
)
123 Input
= stdin
.readline()
124 Input
= Input
.replace('\r', '').replace('\n', '')
126 Logger
.Error("InstallPkg", UNKNOWN_ERROR
, ST
.ERR_USER_INTERRUPT
)
127 Input
= Input
.replace('\r', '').replace('\n', '')
128 return InstallNewFile(WorkspaceDir
, Input
)
136 def UnZipDp(WorkspaceDir
, DpPkgFileName
):
137 ContentZipFile
= None
138 Logger
.Quiet(ST
.MSG_UZIP_PARSE_XML
)
139 DistFile
= PackageFile(DpPkgFileName
)
141 DpDescFileName
, ContentFileName
= GetDPFile(DistFile
.GetZipFile())
143 GlobalData
.gUNPACK_DIR
= os
.path
.normpath(os
.path
.join(WorkspaceDir
, ".tmp"))
144 DistPkgFile
= DistFile
.UnpackFile(DpDescFileName
,
145 os
.path
.normpath(os
.path
.join(GlobalData
.gUNPACK_DIR
, DpDescFileName
)))
147 Logger
.Error("InstallPkg", FILE_NOT_FOUND
, ST
.ERR_FILE_BROKEN
%DpDescFileName
)
152 DistPkgObj
= DistributionPackageXml()
153 DistPkg
= DistPkgObj
.FromXml(DistPkgFile
)
154 if DistPkg
.Header
.RePackage
== '':
155 DistPkg
.Header
.RePackage
= False
156 if DistPkg
.Header
.ReadOnly
== '':
157 DistPkg
.Header
.ReadOnly
= False
160 # unzip contents.zip file
162 ContentFile
= DistFile
.UnpackFile(ContentFileName
,
163 os
.path
.normpath(os
.path
.join(GlobalData
.gUNPACK_DIR
, ContentFileName
)))
165 Logger
.Error("InstallPkg", FILE_NOT_FOUND
,
166 ST
.ERR_FILE_BROKEN
% ContentFileName
)
168 FilePointer
= __FileHookOpen__(ContentFile
, "rb")
170 # Assume no archive comment.
172 FilePointer
.seek(0, SEEK_SET
)
173 FilePointer
.seek(0, SEEK_END
)
177 FileSize
= FilePointer
.tell()
181 ContentZipFile
= PackageFile(ContentFile
)
184 # verify MD5 signature when existed
186 if DistPkg
.Header
.Signature
!= '':
187 Md5Sigature
= md5
.new(__FileHookOpen__(ContentFile
, 'rb').read())
188 if DistPkg
.Header
.Signature
!= Md5Sigature
.hexdigest():
189 ContentZipFile
.Close()
190 Logger
.Error("InstallPkg", FILE_CHECKSUM_FAILURE
,
191 ExtraData
=ContentFile
)
193 return DistPkg
, ContentZipFile
, DpPkgFileName
, DistFile
199 def GetPackageList(DistPkg
, Dep
, WorkspaceDir
, Options
, ContentZipFile
, ModuleList
, PackageList
):
201 for Guid
, Version
, Path
in DistPkg
.PackageSurfaceArea
:
203 Package
= DistPkg
.PackageSurfaceArea
[Guid
, Version
, Path
]
204 Logger
.Info(ST
.MSG_INSTALL_PACKAGE
% Package
.GetName())
205 if Dep
.CheckPackageExists(Guid
, Version
):
206 Logger
.Info(ST
.WRN_PACKAGE_EXISTED
%(Guid
, Version
))
207 if Options
.UseGuidedPkgPath
:
208 GuidedPkgPath
= "%s_%s_%s" % (Package
.GetName(), Guid
, Version
)
209 NewPackagePath
= InstallNewPackage(WorkspaceDir
, GuidedPkgPath
, Options
.CustomPath
)
211 NewPackagePath
= InstallNewPackage(WorkspaceDir
, PackagePath
, Options
.CustomPath
)
212 InstallPackageContent(PackagePath
, NewPackagePath
, Package
, ContentZipFile
, Dep
, WorkspaceDir
, ModuleList
,
213 DistPkg
.Header
.ReadOnly
)
214 PackageList
.append(Package
)
216 NewDict
[Guid
, Version
, Package
.GetPackagePath()] = Package
219 # Now generate meta-data files, first generate all dec for package
220 # dec should be generated before inf, and inf should be generated after
221 # all packages installed, else hard to resolve modules' package
222 # dependency (Hard to get the location of the newly installed package)
224 for Package
in PackageList
:
225 FilePath
= PackageToDec(Package
, DistPkg
.Header
)
226 Md5Sigature
= md5
.new(__FileHookOpen__(str(FilePath
), 'rb').read())
227 Md5Sum
= Md5Sigature
.hexdigest()
228 if (FilePath
, Md5Sum
) not in Package
.FileList
:
229 Package
.FileList
.append((FilePath
, Md5Sum
))
237 def GetModuleList(DistPkg
, Dep
, WorkspaceDir
, ContentZipFile
, ModuleList
):
239 # ModulePathList will keep track of the standalone module path that
240 # we just installed. If a new module's path in that list
241 # (only multiple INF in one directory will be so), we will
242 # install them directly. If not, we will try to create a new directory
248 # Check module exist and install
252 for Guid
, Version
, Name
, Path
in DistPkg
.ModuleSurfaceArea
:
254 Module
= DistPkg
.ModuleSurfaceArea
[Guid
, Version
, Name
, Path
]
255 Logger
.Info(ST
.MSG_INSTALL_MODULE
% Module
.GetName())
256 if Dep
.CheckModuleExists(Guid
, Version
, Name
, Path
):
257 Logger
.Quiet(ST
.WRN_MODULE_EXISTED
%Path
)
259 # here check for the multiple inf share the same module path cases:
260 # they should be installed into the same directory
263 os
.path
.normpath(os
.path
.join(WorkspaceDir
, ModulePath
))
264 if ModuleFullPath
not in ModulePathList
:
265 NewModulePath
= InstallNewModule(WorkspaceDir
, ModulePath
, ModulePathList
)
266 NewModuleFullPath
= os
.path
.normpath(os
.path
.join(WorkspaceDir
, NewModulePath
))
267 ModulePathList
.append(NewModuleFullPath
)
269 NewModulePath
= ModulePath
271 InstallModuleContent(ModulePath
, NewModulePath
, '', Module
, ContentZipFile
, WorkspaceDir
, ModuleList
, None,
272 DistPkg
.Header
.ReadOnly
)
276 Module
.SetModulePath(Module
.GetModulePath().replace(Path
, NewModulePath
, 1))
278 NewDict
[Guid
, Version
, Name
, Module
.GetModulePath()] = Module
281 # generate all inf for modules
283 for (Module
, Package
) in ModuleList
:
284 CheckCNameInModuleRedefined(Module
, DistPkg
)
285 FilePath
= ModuleToInf(Module
, Package
, DistPkg
.Header
)
286 Md5Sigature
= md5
.new(__FileHookOpen__(str(FilePath
), 'rb').read())
287 Md5Sum
= Md5Sigature
.hexdigest()
289 if (FilePath
, Md5Sum
) not in Package
.FileList
:
290 Package
.FileList
.append((FilePath
, Md5Sum
))
292 if (FilePath
, Md5Sum
) not in Module
.FileList
:
293 Module
.FileList
.append((FilePath
, Md5Sum
))
295 # append the module unicode files to Package FileList
297 for (FilePath
, Md5Sum
) in Module
.FileList
:
298 if str(FilePath
).endswith('.uni') and Package
and (FilePath
, Md5Sum
) not in Package
.FileList
:
299 Package
.FileList
.append((FilePath
, Md5Sum
))
304 # Get all protocol/ppi/guid CNames and pcd name from all dependent DEC file
306 def GetDepProtocolPpiGuidPcdNames(DePackageObjList
):
308 # [[Dec1Protocol1, Dec1Protocol2...], [Dec2Protocols...],...]
310 DependentProtocolCNames
= []
311 DependentPpiCNames
= []
312 DependentGuidCNames
= []
313 DependentPcdNames
= []
315 for PackageObj
in DePackageObjList
:
317 # Get protocol CName list from all dependent DEC file
320 for Protocol
in PackageObj
.GetProtocolList():
321 if Protocol
.GetCName() not in ProtocolCNames
:
322 ProtocolCNames
.append(Protocol
.GetCName())
324 DependentProtocolCNames
.append(ProtocolCNames
)
327 # Get Ppi CName list from all dependent DEC file
330 for Ppi
in PackageObj
.GetPpiList():
331 if Ppi
.GetCName() not in PpiCNames
:
332 PpiCNames
.append(Ppi
.GetCName())
334 DependentPpiCNames
.append(PpiCNames
)
337 # Get Guid CName list from all dependent DEC file
340 for Guid
in PackageObj
.GetGuidList():
341 if Guid
.GetCName() not in GuidCNames
:
342 GuidCNames
.append(Guid
.GetCName())
344 DependentGuidCNames
.append(GuidCNames
)
347 # Get PcdName list from all dependent DEC file
350 for Pcd
in PackageObj
.GetPcdList():
351 PcdName
= '.'.join([Pcd
.GetTokenSpaceGuidCName(), Pcd
.GetCName()])
352 if PcdName
not in PcdNames
:
353 PcdNames
.append(PcdName
)
355 DependentPcdNames
.append(PcdNames
)
358 return DependentProtocolCNames
, DependentPpiCNames
, DependentGuidCNames
, DependentPcdNames
361 # Check if protocol CName is redefined
363 def CheckProtoclCNameRedefined(Module
, DependentProtocolCNames
):
364 for ProtocolInModule
in Module
.GetProtocolList():
365 IsCNameDefined
= False
366 for PackageProtocolCNames
in DependentProtocolCNames
:
367 if ProtocolInModule
.GetCName() in PackageProtocolCNames
:
369 Logger
.Error("\nUPT", FORMAT_INVALID
,
370 File
= Module
.GetFullPath(),
372 ST
.ERR_INF_PARSER_ITEM_DUPLICATE_IN_DEC
% ProtocolInModule
.GetCName())
374 IsCNameDefined
= True
377 # Check if Ppi CName is redefined
379 def CheckPpiCNameRedefined(Module
, DependentPpiCNames
):
380 for PpiInModule
in Module
.GetPpiList():
381 IsCNameDefined
= False
382 for PackagePpiCNames
in DependentPpiCNames
:
383 if PpiInModule
.GetCName() in PackagePpiCNames
:
385 Logger
.Error("\nUPT", FORMAT_INVALID
,
386 File
= Module
.GetFullPath(),
387 ExtraData
= ST
.ERR_INF_PARSER_ITEM_DUPLICATE_IN_DEC
% PpiInModule
.GetCName())
389 IsCNameDefined
= True
392 # Check if Guid CName is redefined
394 def CheckGuidCNameRedefined(Module
, DependentGuidCNames
):
395 for GuidInModule
in Module
.GetGuidList():
396 IsCNameDefined
= False
397 for PackageGuidCNames
in DependentGuidCNames
:
398 if GuidInModule
.GetCName() in PackageGuidCNames
:
400 Logger
.Error("\nUPT", FORMAT_INVALID
,
401 File
= Module
.GetFullPath(),
403 ST
.ERR_INF_PARSER_ITEM_DUPLICATE_IN_DEC
% GuidInModule
.GetCName())
405 IsCNameDefined
= True
408 # Check if PcdName is redefined
410 def CheckPcdNameRedefined(Module
, DependentPcdNames
):
412 if not Module
.GetBinaryFileList():
413 PcdObjs
+= Module
.GetPcdList()
415 Binary
= Module
.GetBinaryFileList()[0]
416 for AsBuild
in Binary
.GetAsBuiltList():
417 PcdObjs
+= AsBuild
.GetPatchPcdList() + AsBuild
.GetPcdExList()
419 for PcdObj
in PcdObjs
:
420 PcdName
= '.'.join([PcdObj
.GetTokenSpaceGuidCName(), PcdObj
.GetCName()])
421 IsPcdNameDefined
= False
422 for PcdNames
in DependentPcdNames
:
423 if PcdName
in PcdNames
:
425 Logger
.Error("\nUPT", FORMAT_INVALID
,
426 File
= Module
.GetFullPath(),
427 ExtraData
= ST
.ERR_INF_PARSER_ITEM_DUPLICATE_IN_DEC
% PcdName
)
429 IsPcdNameDefined
= True
432 # Check if any Protocol/Ppi/Guid and Pcd name is redefined in its dependent DEC files
434 def CheckCNameInModuleRedefined(Module
, DistPkg
):
435 DePackageObjList
= []
437 # Get all dependent package objects
439 for Obj
in Module
.GetPackageDependencyList():
441 Version
= Obj
.GetVersion()
442 for Key
in DistPkg
.PackageSurfaceArea
:
443 if Key
[0] == Guid
and Key
[1] == Version
:
444 if DistPkg
.PackageSurfaceArea
[Key
] not in DePackageObjList
:
445 DePackageObjList
.append(DistPkg
.PackageSurfaceArea
[Key
])
447 DependentProtocolCNames
, DependentPpiCNames
, DependentGuidCNames
, DependentPcdNames
= \
448 GetDepProtocolPpiGuidPcdNames(DePackageObjList
)
450 CheckProtoclCNameRedefined(Module
, DependentProtocolCNames
)
451 CheckPpiCNameRedefined(Module
, DependentPpiCNames
)
452 CheckGuidCNameRedefined(Module
, DependentGuidCNames
)
453 CheckPcdNameRedefined(Module
, DependentPcdNames
)
460 def GenToolMisc(DistPkg
, WorkspaceDir
, ContentZipFile
):
461 ToolObject
= DistPkg
.Tools
462 MiscObject
= DistPkg
.MiscellaneousFiles
463 DistPkg
.FileList
= []
467 RootDir
= WorkspaceDir
470 # FileList stores both tools files and misc files
471 # Misc file list must be appended to FileList *AFTER* Tools file list
474 FileList
+= ToolObject
.GetFileList()
475 ToolFileNum
= len(ToolObject
.GetFileList())
476 if 'EDK_TOOLS_PATH' in os
.environ
:
477 RootDir
= os
.environ
['EDK_TOOLS_PATH']
479 FileList
+= MiscObject
.GetFileList()
480 for FileObject
in FileList
:
482 if FileNum
> ToolFileNum
:
484 # Misc files, root should be changed to WORKSPACE
486 RootDir
= WorkspaceDir
487 File
= ConvertPath(FileObject
.GetURI())
488 ToFile
= os
.path
.normpath(os
.path
.join(RootDir
, File
))
489 if os
.path
.exists(ToFile
):
490 Logger
.Info( ST
.WRN_FILE_EXISTED
% ToFile
)
492 # ask for user input the new file name
494 Logger
.Info( ST
.MSG_NEW_FILE_NAME
)
495 Input
= stdin
.readline()
496 Input
= Input
.replace('\r', '').replace('\n', '')
497 OrigPath
= os
.path
.split(ToFile
)[0]
498 ToFile
= os
.path
.normpath(os
.path
.join(OrigPath
, Input
))
499 FromFile
= os
.path
.join(FileObject
.GetURI())
500 Md5Sum
= InstallFile(ContentZipFile
, FromFile
, ToFile
, DistPkg
.Header
.ReadOnly
, FileObject
.GetExecutable())
501 DistPkg
.FileList
.append((ToFile
, Md5Sum
))
503 ## Tool entrance method
505 # This method mainly dispatch specific methods per the command line options.
506 # If no error found, return zero value so the caller of this tool can know
507 # if it's executed successfully or not.
509 # @param Options: command Options
511 def Main(Options
= None):
512 ContentZipFile
, DistFile
= None, None
515 DataBase
= GlobalData
.gDB
516 WorkspaceDir
= GlobalData
.gWORKSPACE
517 if not Options
.PackageFile
:
518 Logger
.Error("InstallPkg", OPTION_MISSING
, ExtraData
=ST
.ERR_SPECIFY_PACKAGE
)
521 # unzip dist.pkg file
523 DistPkg
, ContentZipFile
, DpPkgFileName
, DistFile
= UnZipDp(WorkspaceDir
, Options
.PackageFile
)
528 Dep
= DependencyRules(DataBase
)
529 CheckInstallDpx(Dep
, DistPkg
)
532 # Install distribution
534 InstallDp(DistPkg
, DpPkgFileName
, ContentZipFile
, Options
, Dep
, WorkspaceDir
, DataBase
)
537 except FatalError
, XExcept
:
538 ReturnCode
= XExcept
.args
[0]
539 if Logger
.GetLevel() <= Logger
.DEBUG_9
:
540 Logger
.Quiet(ST
.MSG_PYTHON_ON
% (python_version(), platform
) + format_exc())
542 except KeyboardInterrupt:
543 ReturnCode
= ABORT_ERROR
544 if Logger
.GetLevel() <= Logger
.DEBUG_9
:
545 Logger
.Quiet(ST
.MSG_PYTHON_ON
% (python_version(), platform
) + format_exc())
548 ReturnCode
= CODE_ERROR
552 ST
.ERR_UNKNOWN_FATAL_INSTALL_ERR
% Options
.PackageFile
,
553 ExtraData
=ST
.MSG_SEARCH_FOR_HELP
,
556 Logger
.Quiet(ST
.MSG_PYTHON_ON
% (python_version(),
557 platform
) + format_exc())
559 if ReturnCode
!= UPT_ALREADY_INSTALLED_ERROR
:
560 Logger
.Quiet(ST
.MSG_REMOVE_TEMP_FILE_STARTED
)
564 ContentZipFile
.Close()
565 if GlobalData
.gUNPACK_DIR
:
566 rmtree(GlobalData
.gUNPACK_DIR
)
567 GlobalData
.gUNPACK_DIR
= None
568 Logger
.Quiet(ST
.MSG_REMOVE_TEMP_FILE_DONE
)
570 Logger
.Quiet(ST
.MSG_FINISH
)
575 # This method will backup the Distribution file into the $(WORKSPACE)/conf/upt, and rename it
576 # if there is already a same-named distribution existed.
578 # @param DpPkgFileName: The distribution path
579 # @param Guid: The distribution Guid
580 # @param Version: The distribution Version
581 # @param WorkspaceDir: The workspace directory
582 # @retval NewDpPkgFileName: The exact backup file name
584 def BackupDist(DpPkgFileName
, Guid
, Version
, WorkspaceDir
):
585 DistFileName
= os
.path
.split(DpPkgFileName
)[1]
586 DestDir
= os
.path
.normpath(os
.path
.join(WorkspaceDir
, GlobalData
.gUPT_DIR
))
587 CreateDirectory(DestDir
)
588 DestFile
= os
.path
.normpath(os
.path
.join(DestDir
, DistFileName
))
589 if os
.path
.exists(DestFile
):
590 FileName
, Ext
= os
.path
.splitext(DistFileName
)
591 NewFileName
= FileName
+ '_' + Guid
+ '_' + Version
+ Ext
592 DestFile
= os
.path
.normpath(os
.path
.join(DestDir
, NewFileName
))
593 if os
.path
.exists(DestFile
):
595 # ask for user input the new file name
597 Logger
.Info( ST
.MSG_NEW_FILE_NAME_FOR_DIST
)
598 Input
= stdin
.readline()
599 Input
= Input
.replace('\r', '').replace('\n', '')
600 DestFile
= os
.path
.normpath(os
.path
.join(DestDir
, Input
))
601 copyfile(DpPkgFileName
, DestFile
)
602 NewDpPkgFileName
= DestFile
[DestFile
.find(DestDir
) + len(DestDir
) + 1:]
603 return NewDpPkgFileName
605 ## CheckInstallDpx method
607 # check whether distribution could be installed
609 # @param Dep: the DependencyRules instance that used to check dependency
610 # @param DistPkg: the distribution object
612 def CheckInstallDpx(Dep
, DistPkg
):
614 # Check distribution package installed or not
616 if Dep
.CheckDpExists(DistPkg
.Header
.GetGuid(),
617 DistPkg
.Header
.GetVersion()):
618 Logger
.Error("InstallPkg", UPT_ALREADY_INSTALLED_ERROR
,
619 ST
.WRN_DIST_PKG_INSTALLED
)
621 # Check distribution dependency (all module dependency should be
624 if not Dep
.CheckInstallDpDepexSatisfied(DistPkg
):
625 Logger
.Error("InstallPkg", UNKNOWN_ERROR
,
626 ST
.ERR_PACKAGE_NOT_MATCH_DEPENDENCY
,
627 ExtraData
=DistPkg
.Header
.Name
)
629 ## InstallModuleContent method
631 # If this is standalone module, then Package should be none,
632 # ModulePath should be ''
633 # @param FromPath: FromPath
634 # @param NewPath: NewPath
635 # @param ModulePath: ModulePath
636 # @param Module: Module
637 # @param ContentZipFile: ContentZipFile
638 # @param WorkspaceDir: WorkspaceDir
639 # @param ModuleList: ModuleList
640 # @param Package: Package
642 def InstallModuleContent(FromPath
, NewPath
, ModulePath
, Module
, ContentZipFile
,
643 WorkspaceDir
, ModuleList
, Package
= None, ReadOnly
= False):
645 if NewPath
.startswith("\\") or NewPath
.startswith("/"):
646 NewPath
= NewPath
[1:]
648 if not IsValidInstallPath(NewPath
):
649 Logger
.Error("UPT", FORMAT_INVALID
, ST
.ERR_FILE_NAME_INVALIDE
%NewPath
)
651 NewModuleFullPath
= os
.path
.normpath(os
.path
.join(WorkspaceDir
, NewPath
,
652 ConvertPath(ModulePath
)))
653 Module
.SetFullPath(os
.path
.normpath(os
.path
.join(NewModuleFullPath
,
654 ConvertPath(Module
.GetName()) + '.inf')))
657 for MiscFile
in Module
.GetMiscFileList():
660 for Item
in MiscFile
.GetFileList():
662 if File
.startswith("\\") or File
.startswith("/"):
665 if not IsValidInstallPath(File
):
666 Logger
.Error("UPT", FORMAT_INVALID
, ST
.ERR_FILE_NAME_INVALIDE
%File
)
668 FromFile
= os
.path
.join(FromPath
, ModulePath
, File
)
669 Executable
= Item
.GetExecutable()
670 ToFile
= os
.path
.normpath(os
.path
.join(NewModuleFullPath
, ConvertPath(File
)))
671 Md5Sum
= InstallFile(ContentZipFile
, FromFile
, ToFile
, ReadOnly
, Executable
)
672 if Package
and ((ToFile
, Md5Sum
) not in Package
.FileList
):
673 Package
.FileList
.append((ToFile
, Md5Sum
))
676 elif (ToFile
, Md5Sum
) not in Module
.FileList
:
677 Module
.FileList
.append((ToFile
, Md5Sum
))
678 for Item
in Module
.GetSourceFileList():
679 File
= Item
.GetSourceFile()
680 if File
.startswith("\\") or File
.startswith("/"):
683 if not IsValidInstallPath(File
):
684 Logger
.Error("UPT", FORMAT_INVALID
, ST
.ERR_FILE_NAME_INVALIDE
%File
)
686 FromFile
= os
.path
.join(FromPath
, ModulePath
, File
)
687 ToFile
= os
.path
.normpath(os
.path
.join(NewModuleFullPath
, ConvertPath(File
)))
688 Md5Sum
= InstallFile(ContentZipFile
, FromFile
, ToFile
, ReadOnly
)
689 if Package
and ((ToFile
, Md5Sum
) not in Package
.FileList
):
690 Package
.FileList
.append((ToFile
, Md5Sum
))
693 elif (ToFile
, Md5Sum
) not in Module
.FileList
:
694 Module
.FileList
.append((ToFile
, Md5Sum
))
695 for Item
in Module
.GetBinaryFileList():
696 FileNameList
= Item
.GetFileNameList()
697 for FileName
in FileNameList
:
698 File
= FileName
.GetFilename()
699 if File
.startswith("\\") or File
.startswith("/"):
702 if not IsValidInstallPath(File
):
703 Logger
.Error("UPT", FORMAT_INVALID
, ST
.ERR_FILE_NAME_INVALIDE
%File
)
705 FromFile
= os
.path
.join(FromPath
, ModulePath
, File
)
706 ToFile
= os
.path
.normpath(os
.path
.join(NewModuleFullPath
, ConvertPath(File
)))
707 Md5Sum
= InstallFile(ContentZipFile
, FromFile
, ToFile
, ReadOnly
)
708 if Package
and ((ToFile
, Md5Sum
) not in Package
.FileList
):
709 Package
.FileList
.append((ToFile
, Md5Sum
))
712 elif (ToFile
, Md5Sum
) not in Module
.FileList
:
713 Module
.FileList
.append((ToFile
, Md5Sum
))
715 InstallModuleContentZipFile(ContentZipFile
, FromPath
, ModulePath
, WorkspaceDir
, NewPath
, Module
, Package
, ReadOnly
,
718 ## InstallModuleContentZipFile
720 # InstallModuleContentZipFile
722 def InstallModuleContentZipFile(ContentZipFile
, FromPath
, ModulePath
, WorkspaceDir
, NewPath
, Module
, Package
, ReadOnly
,
725 # Extract other files under current module path in content Zip file but not listed in the description
728 for FileName
in ContentZipFile
.GetZipFile().namelist():
729 FileName
= os
.path
.normpath(FileName
)
730 CheckPath
= os
.path
.normpath(os
.path
.join(FromPath
, ModulePath
))
731 if FileUnderPath(FileName
, CheckPath
):
732 if FileName
.startswith("\\") or FileName
.startswith("/"):
733 FileName
= FileName
[1:]
735 if not IsValidInstallPath(FileName
):
736 Logger
.Error("UPT", FORMAT_INVALID
, ST
.ERR_FILE_NAME_INVALIDE
%FileName
)
739 ToFile
= os
.path
.normpath(os
.path
.join(WorkspaceDir
,
740 ConvertPath(FileName
.replace(FromPath
, NewPath
, 1))))
741 CheckList
= copy
.copy(Module
.FileList
)
743 CheckList
+= Package
.FileList
744 for Item
in CheckList
:
745 if Item
[0] == ToFile
:
748 Md5Sum
= InstallFile(ContentZipFile
, FromFile
, ToFile
, ReadOnly
)
749 if Package
and ((ToFile
, Md5Sum
) not in Package
.FileList
):
750 Package
.FileList
.append((ToFile
, Md5Sum
))
753 elif (ToFile
, Md5Sum
) not in Module
.FileList
:
754 Module
.FileList
.append((ToFile
, Md5Sum
))
756 ModuleList
.append((Module
, Package
))
759 # Check whether FileName started with directory specified by CheckPath
761 # @param FileName: the FileName need to be checked
762 # @param CheckPath: the path need to be checked against
763 # @return: True or False
765 def FileUnderPath(FileName
, CheckPath
):
766 FileName
= FileName
.replace('\\', '/')
767 FileName
= os
.path
.normpath(FileName
)
768 CheckPath
= CheckPath
.replace('\\', '/')
769 CheckPath
= os
.path
.normpath(CheckPath
)
770 if FileName
.startswith(CheckPath
):
771 RemainingPath
= os
.path
.normpath(FileName
.replace(CheckPath
, '', 1))
772 while RemainingPath
.startswith('\\') or RemainingPath
.startswith('/'):
773 RemainingPath
= RemainingPath
[1:]
774 if FileName
== os
.path
.normpath(os
.path
.join(CheckPath
, RemainingPath
)):
780 # Extract File from Zipfile, set file attribute, and return the Md5Sum
782 # @return: True or False
784 def InstallFile(ContentZipFile
, FromFile
, ToFile
, ReadOnly
, Executable
=False):
785 if os
.path
.exists(os
.path
.normpath(ToFile
)):
788 if not ContentZipFile
or not ContentZipFile
.UnpackFile(FromFile
, ToFile
):
789 Logger
.Error("UPT", FILE_NOT_FOUND
, ST
.ERR_INSTALL_FILE_FROM_EMPTY_CONTENT
% FromFile
)
793 chmod(ToFile
, stat
.S_IRUSR | stat
.S_IRGRP | stat
.S_IROTH
)
795 chmod(ToFile
, stat
.S_IRUSR | stat
.S_IRGRP | stat
.S_IROTH | stat
.S_IEXEC | stat
.S_IXGRP | stat
.S_IXOTH
)
797 chmod(ToFile
, stat
.S_IRUSR | stat
.S_IRGRP | stat
.S_IROTH | stat
.S_IWUSR | stat
.S_IWGRP |
798 stat
.S_IWOTH | stat
.S_IEXEC | stat
.S_IXGRP | stat
.S_IXOTH
)
800 chmod(ToFile
, stat
.S_IRUSR | stat
.S_IRGRP | stat
.S_IROTH | stat
.S_IWUSR | stat
.S_IWGRP | stat
.S_IWOTH
)
802 Md5Sigature
= md5
.new(__FileHookOpen__(str(ToFile
), 'rb').read())
803 Md5Sum
= Md5Sigature
.hexdigest()
807 ## InstallPackageContent method
809 # @param FromPath: FromPath
810 # @param ToPath: ToPath
811 # @param Package: Package
812 # @param ContentZipFile: ContentZipFile
814 # @param WorkspaceDir: WorkspaceDir
815 # @param ModuleList: ModuleList
817 def InstallPackageContent(FromPath
, ToPath
, Package
, ContentZipFile
, Dep
,
818 WorkspaceDir
, ModuleList
, ReadOnly
= False):
821 Package
.FileList
= []
823 if ToPath
.startswith("\\") or ToPath
.startswith("/"):
826 if not IsValidInstallPath(ToPath
):
827 Logger
.Error("UPT", FORMAT_INVALID
, ST
.ERR_FILE_NAME_INVALIDE
%ToPath
)
829 if FromPath
.startswith("\\") or FromPath
.startswith("/"):
830 FromPath
= FromPath
[1:]
832 if not IsValidInstallPath(FromPath
):
833 Logger
.Error("UPT", FORMAT_INVALID
, ST
.ERR_FILE_NAME_INVALIDE
%FromPath
)
835 PackageFullPath
= os
.path
.normpath(os
.path
.join(WorkspaceDir
, ToPath
))
836 for MiscFile
in Package
.GetMiscFileList():
837 for Item
in MiscFile
.GetFileList():
838 FileName
= Item
.GetURI()
839 if FileName
.startswith("\\") or FileName
.startswith("/"):
840 FileName
= FileName
[1:]
842 if not IsValidInstallPath(FileName
):
843 Logger
.Error("UPT", FORMAT_INVALID
, ST
.ERR_FILE_NAME_INVALIDE
%FileName
)
845 FromFile
= os
.path
.join(FromPath
, FileName
)
846 Executable
= Item
.GetExecutable()
847 ToFile
= (os
.path
.join(PackageFullPath
, ConvertPath(FileName
)))
848 Md5Sum
= InstallFile(ContentZipFile
, FromFile
, ToFile
, ReadOnly
, Executable
)
849 if (ToFile
, Md5Sum
) not in Package
.FileList
:
850 Package
.FileList
.append((ToFile
, Md5Sum
))
851 PackageIncludeArchList
= []
852 for Item
in Package
.GetPackageIncludeFileList():
853 FileName
= Item
.GetFilePath()
854 if FileName
.startswith("\\") or FileName
.startswith("/"):
855 FileName
= FileName
[1:]
857 if not IsValidInstallPath(FileName
):
858 Logger
.Error("UPT", FORMAT_INVALID
, ST
.ERR_FILE_NAME_INVALIDE
%FileName
)
860 FromFile
= os
.path
.join(FromPath
, FileName
)
861 ToFile
= os
.path
.normpath(os
.path
.join(PackageFullPath
, ConvertPath(FileName
)))
862 RetFile
= ContentZipFile
.UnpackFile(FromFile
, ToFile
)
865 # a non-exist path in Zipfile will return '', which means an include directory in our case
866 # save the information for later DEC creation usage and also create the directory
868 PackageIncludeArchList
.append([Item
.GetFilePath(), Item
.GetSupArchList()])
869 CreateDirectory(ToFile
)
872 chmod(ToFile
, stat
.S_IRUSR|stat
.S_IRGRP|stat
.S_IROTH
)
874 chmod(ToFile
, stat
.S_IRUSR|stat
.S_IRGRP|stat
.S_IROTH|stat
.S_IWUSR|stat
.S_IWGRP|stat
.S_IWOTH
)
875 Md5Sigature
= md5
.new(__FileHookOpen__(str(ToFile
), 'rb').read())
876 Md5Sum
= Md5Sigature
.hexdigest()
877 if (ToFile
, Md5Sum
) not in Package
.FileList
:
878 Package
.FileList
.append((ToFile
, Md5Sum
))
879 Package
.SetIncludeArchList(PackageIncludeArchList
)
881 for Item
in Package
.GetStandardIncludeFileList():
882 FileName
= Item
.GetFilePath()
883 if FileName
.startswith("\\") or FileName
.startswith("/"):
884 FileName
= FileName
[1:]
886 if not IsValidInstallPath(FileName
):
887 Logger
.Error("UPT", FORMAT_INVALID
, ST
.ERR_FILE_NAME_INVALIDE
%FileName
)
889 FromFile
= os
.path
.join(FromPath
, FileName
)
890 ToFile
= os
.path
.normpath(os
.path
.join(PackageFullPath
, ConvertPath(FileName
)))
891 Md5Sum
= InstallFile(ContentZipFile
, FromFile
, ToFile
, ReadOnly
)
892 if (ToFile
, Md5Sum
) not in Package
.FileList
:
893 Package
.FileList
.append((ToFile
, Md5Sum
))
898 Package
.SetPackagePath(Package
.GetPackagePath().replace(FromPath
,
900 Package
.SetFullPath(os
.path
.normpath(os
.path
.join(PackageFullPath
,
901 ConvertPath(Package
.GetName()) + '.dec')))
904 # Install files in module
907 ModuleDict
= Package
.GetModuleDict()
908 for ModuleGuid
, ModuleVersion
, ModuleName
, ModulePath
in ModuleDict
:
909 Module
= ModuleDict
[ModuleGuid
, ModuleVersion
, ModuleName
, ModulePath
]
910 InstallModuleContent(FromPath
, ToPath
, ModulePath
, Module
,
911 ContentZipFile
, WorkspaceDir
, ModuleList
, Package
, ReadOnly
)
915 # @param ZipFile: A ZipFile
917 def GetDPFile(ZipFile
):
920 for FileName
in ZipFile
.namelist():
921 if FileName
.endswith('.content'):
923 ContentFile
= FileName
925 elif FileName
.endswith('.pkg'):
932 Logger
.Error("PackagingTool", FILE_TYPE_MISMATCH
,
933 ExtraData
=ST
.ERR_DIST_FILE_TOOMANY
)
934 if not DescFile
or not ContentFile
:
935 Logger
.Error("PackagingTool", FILE_UNKNOWN_ERROR
,
936 ExtraData
=ST
.ERR_DIST_FILE_TOOFEW
)
937 return DescFile
, ContentFile
941 # Install the distribution to current workspace
943 def InstallDp(DistPkg
, DpPkgFileName
, ContentZipFile
, Options
, Dep
, WorkspaceDir
, DataBase
):
945 # PackageList, ModuleList record the information for the meta-data
946 # files that need to be generated later
950 DistPkg
.PackageSurfaceArea
= GetPackageList(DistPkg
, Dep
, WorkspaceDir
, Options
,
951 ContentZipFile
, ModuleList
, PackageList
)
953 DistPkg
.ModuleSurfaceArea
= GetModuleList(DistPkg
, Dep
, WorkspaceDir
, ContentZipFile
, ModuleList
)
955 GenToolMisc(DistPkg
, WorkspaceDir
, ContentZipFile
)
958 # copy "Distribution File" to directory $(WORKSPACE)/conf/upt
960 DistFileName
= os
.path
.split(DpPkgFileName
)[1]
961 NewDpPkgFileName
= BackupDist(DpPkgFileName
, DistPkg
.Header
.GetGuid(), DistPkg
.Header
.GetVersion(), WorkspaceDir
)
966 Logger
.Quiet(ST
.MSG_UPDATE_PACKAGE_DATABASE
)
967 DataBase
.AddDPObject(DistPkg
, NewDpPkgFileName
, DistFileName
,
968 DistPkg
.Header
.RePackage
)