mirror of
				https://git.proxmox.com/git/mirror_edk2
				synced 2025-10-31 01:35:30 +00:00 
			
		
		
		
	 4234283c3a
			
		
	
	
		4234283c3a
		
	
	
	
	
		
			
			BaseTool Branch: https://edk2-buildtools.svn.sourceforge.net/svnroot/edk2-buildtools/branches/Releases/BaseTools_r2100 Signed-off-by: lgao4 Reviewed-by: hchen30 git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12214 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			771 lines
		
	
	
		
			29 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			771 lines
		
	
	
		
			29 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| ## @file
 | |
| # Install distribution package.
 | |
| #
 | |
| # Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
 | |
| #
 | |
| # This program and the accompanying materials are licensed and made available 
 | |
| # under the terms and conditions of the BSD License which accompanies this 
 | |
| # distribution. The full text of the license may be found at 
 | |
| # http://opensource.org/licenses/bsd-license.php
 | |
| #
 | |
| # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | |
| # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | |
| #
 | |
| """
 | |
| Install a distribution package
 | |
| """
 | |
| ##
 | |
| # Import Modules
 | |
| #
 | |
| import os.path
 | |
| from os import chmod
 | |
| from os import SEEK_SET
 | |
| from os import SEEK_END
 | |
| import stat
 | |
| import md5
 | |
| from sys import stdin
 | |
| from sys import platform
 | |
| from shutil import rmtree
 | |
| from shutil import copyfile
 | |
| from traceback import format_exc
 | |
| from platform import python_version
 | |
| 
 | |
| from Logger import StringTable as ST
 | |
| from Logger.ToolError import UNKNOWN_ERROR
 | |
| from Logger.ToolError import FILE_UNKNOWN_ERROR
 | |
| from Logger.ToolError import OPTION_MISSING
 | |
| from Logger.ToolError import UPT_ALREADY_INSTALLED_ERROR
 | |
| from Logger.ToolError import FatalError
 | |
| from Logger.ToolError import ABORT_ERROR
 | |
| from Logger.ToolError import CODE_ERROR
 | |
| from Logger.ToolError import FORMAT_INVALID
 | |
| from Logger.ToolError import FILE_TYPE_MISMATCH
 | |
| import Logger.Log as Logger
 | |
| 
 | |
| from Library.Misc import CheckEnvVariable
 | |
| from Library.Misc import Sdict
 | |
| from Library.Misc import ConvertPath
 | |
| from Library.ParserValidate import IsValidInstallPath
 | |
| from Xml.XmlParser import DistributionPackageXml
 | |
| from GenMetaFile.GenDecFile import PackageToDec
 | |
| from GenMetaFile.GenInfFile import ModuleToInf
 | |
| from Core.PackageFile import PackageFile
 | |
| from Core.PackageFile import FILE_NOT_FOUND
 | |
| from Core.PackageFile import FILE_CHECKSUM_FAILURE
 | |
| from Core.PackageFile import CreateDirectory
 | |
| from Core.DependencyRules import DependencyRules
 | |
| from Library import GlobalData
 | |
| 
 | |
| ## InstallNewPackage
 | |
| #
 | |
| # @param WorkspaceDir:   Workspace Directory
 | |
| # @param Path:           Package Path
 | |
| # @param CustomPath:     whether need to customize path at first
 | |
| #
 | |
| def InstallNewPackage(WorkspaceDir, Path, CustomPath = False):
 | |
|     if os.path.isabs(Path):
 | |
|         Logger.Info(ST.MSG_RELATIVE_PATH_ONLY%Path)
 | |
|     elif CustomPath:
 | |
|         Logger.Info(ST.MSG_NEW_PKG_PATH)
 | |
|     else:
 | |
|         Path = ConvertPath(Path)
 | |
|         Path = os.path.normpath(Path)
 | |
|         FullPath = os.path.normpath(os.path.join(WorkspaceDir, Path))
 | |
|         if os.path.exists(FullPath):
 | |
|             Logger.Info(ST.ERR_DIR_ALREADY_EXIST%FullPath)
 | |
|         else:
 | |
|             return Path
 | |
| 
 | |
|     Input = stdin.readline()
 | |
|     Input = Input.replace('\r', '').replace('\n', '')
 | |
|     if Input == '':
 | |
|         Logger.Error("InstallPkg", UNKNOWN_ERROR, ST.ERR_USER_INTERRUPT)
 | |
|     Input = Input.replace('\r', '').replace('\n', '')
 | |
|     return InstallNewPackage(WorkspaceDir, Input, False)
 | |
| 
 | |
| 
 | |
| ## InstallNewModule
 | |
| #
 | |
| # @param WorkspaceDir:   Workspace Directory
 | |
| # @param Path:           Standalone Module Path
 | |
| # @param PathList:       The already installed standalone module Path list
 | |
| #
 | |
| def InstallNewModule(WorkspaceDir, Path, PathList = None):
 | |
|     if PathList == None:
 | |
|         PathList = []
 | |
|     Path = ConvertPath(Path)
 | |
|     Path = os.path.normpath(Path)
 | |
|     FullPath = os.path.normpath(os.path.join(WorkspaceDir, Path))
 | |
|     if os.path.exists(FullPath) and FullPath not in PathList:
 | |
|         Logger.Info(ST.ERR_DIR_ALREADY_EXIST%Path)
 | |
|     elif Path == FullPath:
 | |
|         Logger.Info(ST.MSG_RELATIVE_PATH_ONLY%FullPath)
 | |
|     else:
 | |
|         return Path
 | |
|     
 | |
|     Input = stdin.readline()
 | |
|     Input = Input.replace('\r', '').replace('\n', '')
 | |
|     if Input == '':
 | |
|         Logger.Error("InstallPkg", UNKNOWN_ERROR, ST.ERR_USER_INTERRUPT)
 | |
|     Input = Input.replace('\r', '').replace('\n', '')
 | |
|     return InstallNewModule(WorkspaceDir, Input, PathList)
 | |
| 
 | |
|     
 | |
| ## InstallNewFile
 | |
| #
 | |
| # @param WorkspaceDir:   Workspace Direction
 | |
| # @param File:      File
 | |
| #
 | |
| def InstallNewFile(WorkspaceDir, File):
 | |
|     FullPath = os.path.normpath(os.path.join(WorkspaceDir, File))
 | |
|     if os.path.exists(FullPath):
 | |
|         Logger.Info(ST.ERR_FILE_ALREADY_EXIST %File)
 | |
|         Input = stdin.readline()
 | |
|         Input = Input.replace('\r', '').replace('\n', '')
 | |
|         if Input == '':
 | |
|             Logger.Error("InstallPkg", UNKNOWN_ERROR, ST.ERR_USER_INTERRUPT)
 | |
|         Input = Input.replace('\r', '').replace('\n', '')
 | |
|         return InstallNewFile(WorkspaceDir, Input)
 | |
|     else:
 | |
|         return File
 | |
| 
 | |
| ## UnZipDp
 | |
| #
 | |
| # UnZipDp
 | |
| #
 | |
| def UnZipDp(WorkspaceDir, Options, DataBase):
 | |
|     ContentZipFile = None
 | |
|     Logger.Quiet(ST.MSG_UZIP_PARSE_XML)
 | |
|     DpPkgFileName = Options.PackageFile
 | |
|     DistFile = PackageFile(DpPkgFileName)
 | |
|     
 | |
|     DpDescFileName, ContentFileName = GetDPFile(DistFile.GetZipFile())
 | |
|     
 | |
|     GlobalData.gUNPACK_DIR = os.path.normpath(os.path.join(WorkspaceDir, ".tmp"))
 | |
|     DistPkgFile = DistFile.UnpackFile(DpDescFileName,
 | |
|         os.path.normpath(os.path.join(GlobalData.gUNPACK_DIR, DpDescFileName)))
 | |
|     if not DistPkgFile:
 | |
|         Logger.Error("InstallPkg", FILE_NOT_FOUND, ST.ERR_FILE_BROKEN %DpDescFileName)
 | |
|     
 | |
|     #
 | |
|     # Generate distpkg
 | |
|     #
 | |
|     DistPkgObj = DistributionPackageXml()
 | |
|     DistPkg = DistPkgObj.FromXml(DistPkgFile)
 | |
|     if DistPkg.Header.RePackage == '':
 | |
|         DistPkg.Header.RePackage = False
 | |
|     if DistPkg.Header.ReadOnly == '':
 | |
|         DistPkg.Header.ReadOnly = False
 | |
|     
 | |
|     #
 | |
|     # prepare check dependency
 | |
|     #
 | |
|     Dep = DependencyRules(DataBase)
 | |
|     #
 | |
|     # Check distribution package installed or not
 | |
|     #
 | |
|     if Dep.CheckDpExists(DistPkg.Header.GetGuid(),
 | |
|         DistPkg.Header.GetVersion()):
 | |
|         Logger.Error("InstallPkg", UPT_ALREADY_INSTALLED_ERROR,
 | |
|             ST.WRN_DIST_PKG_INSTALLED)
 | |
|     #
 | |
|     # Check distribution dependency (all module dependency should be
 | |
|     # satisfied)
 | |
|     #
 | |
|     if not Dep.CheckDpDepexSatisfied(DistPkg):
 | |
|         Logger.Error("InstallPkg", UNKNOWN_ERROR,
 | |
|             ST.ERR_PACKAGE_NOT_MATCH_DEPENDENCY,
 | |
|             ExtraData=DistPkg.Header.Name)
 | |
|     #
 | |
|     # unzip contents.zip file
 | |
|     #
 | |
|     ContentFile = DistFile.UnpackFile(ContentFileName,
 | |
|         os.path.normpath(os.path.join(GlobalData.gUNPACK_DIR, ContentFileName)))
 | |
|     if not ContentFile:
 | |
|         Logger.Error("InstallPkg", FILE_NOT_FOUND,
 | |
|             ST.ERR_FILE_BROKEN % ContentFileName)
 | |
| 
 | |
|     FilePointer = open(ContentFile, "rb")
 | |
|     #
 | |
|     # Assume no archive comment.
 | |
|     #
 | |
|     FilePointer.seek(0, SEEK_SET)
 | |
|     FilePointer.seek(0, SEEK_END)
 | |
|     #
 | |
|     # Get file size
 | |
|     #                
 | |
|     FileSize = FilePointer.tell()
 | |
|     FilePointer.close()
 | |
|                
 | |
|     if FileSize != 0:        
 | |
|         ContentZipFile = PackageFile(ContentFile)
 | |
| 
 | |
|     #
 | |
|     # verify MD5 signature when existed
 | |
|     #
 | |
|     if DistPkg.Header.Signature != '':
 | |
|         Md5Sigature = md5.new(open(ContentFile, 'rb').read())
 | |
|         if DistPkg.Header.Signature != Md5Sigature.hexdigest():
 | |
|             ContentZipFile.Close()
 | |
|             Logger.Error("InstallPkg", FILE_CHECKSUM_FAILURE,
 | |
|                 ExtraData=ContentFile)
 | |
| 
 | |
|     return DistPkg, Dep, ContentZipFile, DpPkgFileName
 | |
| 
 | |
| ## GetPackageList
 | |
| #
 | |
| # GetPackageList
 | |
| #
 | |
| def GetPackageList(DistPkg, Dep, WorkspaceDir, Options, ContentZipFile, ModuleList, PackageList):
 | |
|     NewDict = Sdict()
 | |
|     for Guid, Version, Path in DistPkg.PackageSurfaceArea:
 | |
|         PackagePath = Path
 | |
|         Package = DistPkg.PackageSurfaceArea[Guid, Version, Path]
 | |
|         Logger.Info(ST.MSG_INSTALL_PACKAGE % Package.GetName())
 | |
|         if Dep.CheckPackageExists(Guid, Version):
 | |
|             Logger.Info(ST.WRN_PACKAGE_EXISTED %(Guid, Version))
 | |
|         NewPackagePath = InstallNewPackage(WorkspaceDir, PackagePath, Options.CustomPath)
 | |
|         InstallPackageContent(PackagePath, NewPackagePath, Package, ContentZipFile, Dep, WorkspaceDir, ModuleList, 
 | |
|                               DistPkg.Header.ReadOnly)
 | |
|         PackageList.append(Package)
 | |
|         
 | |
|         NewDict[Guid, Version, Package.GetPackagePath()] = Package
 | |
|     
 | |
|     #
 | |
|     # Now generate meta-data files, first generate all dec for package
 | |
|     # dec should be generated before inf, and inf should be generated after
 | |
|     # all packages installed, else hard to resolve modules' package
 | |
|     # dependency (Hard to get the location of the newly installed package)
 | |
|     #
 | |
|     for Package in PackageList:
 | |
|         FilePath = PackageToDec(Package)
 | |
|         Md5Sigature = md5.new(open(str(FilePath), 'rb').read())
 | |
|         Md5Sum = Md5Sigature.hexdigest()
 | |
|         if (FilePath, Md5Sum) not in Package.FileList:
 | |
|             Package.FileList.append((FilePath, Md5Sum))
 | |
|     
 | |
|     return NewDict
 | |
| 
 | |
| ## GetModuleList
 | |
| #
 | |
| # GetModuleList
 | |
| #
 | |
| def GetModuleList(DistPkg, Dep, WorkspaceDir, ContentZipFile, ModuleList):
 | |
|     #
 | |
|     # ModulePathList will keep track of the standalone module path that
 | |
|     # we just installed. If a new module's path in that list 
 | |
|     # (only multiple INF in one directory will be so), we will 
 | |
|     # install them directly. If not, we will try to create a new directory 
 | |
|     # for it.
 | |
|     #
 | |
|     ModulePathList = []   
 | |
|     
 | |
|     #
 | |
|     # Check module exist and install
 | |
|     #
 | |
|     Module = None
 | |
|     NewDict = Sdict()        
 | |
|     for Guid, Version, Path in DistPkg.ModuleSurfaceArea:
 | |
|         ModulePath = Path
 | |
|         Module = DistPkg.ModuleSurfaceArea[Guid, Version, Path]
 | |
|         Logger.Info(ST.MSG_INSTALL_MODULE % Module.GetName())
 | |
|         if Dep.CheckModuleExists(Guid, Version):
 | |
|             Logger.Quiet(ST.WRN_MODULE_EXISTED %Path)
 | |
|         #
 | |
|         # here check for the multiple inf share the same module path cases:
 | |
|         # they should be installed into the same directory
 | |
|         #
 | |
|         ModuleFullPath = \
 | |
|         os.path.normpath(os.path.join(WorkspaceDir, ModulePath))
 | |
|         if ModuleFullPath not in ModulePathList:
 | |
|             NewModulePath = InstallNewModule(WorkspaceDir, ModulePath, ModulePathList)
 | |
|             NewModuleFullPath = os.path.normpath(os.path.join(WorkspaceDir, NewModulePath))
 | |
|             ModulePathList.append(NewModuleFullPath)
 | |
|         else:
 | |
|             NewModulePath = ModulePath
 | |
|         
 | |
|         InstallModuleContent(ModulePath, NewModulePath, '', Module, ContentZipFile, WorkspaceDir, ModuleList, None, 
 | |
|                              DistPkg.Header.ReadOnly)
 | |
|         #
 | |
|         # Update module
 | |
|         #
 | |
|         Module.SetModulePath(Module.GetModulePath().replace(Path, NewModulePath, 1))
 | |
|         
 | |
|         NewDict[Guid, Version, Module.GetModulePath()] = Module
 | |
| 
 | |
|     #
 | |
|     # generate all inf for modules
 | |
|     #
 | |
|     for (Module, Package) in ModuleList:
 | |
|         FilePath = ModuleToInf(Module)
 | |
|         Md5Sigature = md5.new(open(str(FilePath), 'rb').read())
 | |
|         Md5Sum = Md5Sigature.hexdigest()
 | |
|         if Package:
 | |
|             if (FilePath, Md5Sum) not in Package.FileList:
 | |
|                 Package.FileList.append((FilePath, Md5Sum))
 | |
|         else:
 | |
|             if (FilePath, Md5Sum) not in Module.FileList:
 | |
|                 Module.FileList.append((FilePath, Md5Sum))
 | |
|     
 | |
|     return NewDict
 | |
| 
 | |
| ## GenToolMisc
 | |
| #
 | |
| # GenToolMisc
 | |
| #
 | |
| #
 | |
| def GenToolMisc(DistPkg, WorkspaceDir, ContentZipFile):
 | |
|     ToolObject = DistPkg.Tools
 | |
|     MiscObject = DistPkg.MiscellaneousFiles
 | |
|     DistPkg.FileList = []
 | |
|     FileList = []
 | |
|     ToolFileNum = 0
 | |
|     FileNum = 0
 | |
|     RootDir = WorkspaceDir
 | |
|     
 | |
|     #
 | |
|     # FileList stores both tools files and misc files
 | |
|     # Misc file list must be appended to FileList *AFTER* Tools file list
 | |
|     #
 | |
|     if ToolObject:
 | |
|         FileList += ToolObject.GetFileList()
 | |
|         ToolFileNum = len(ToolObject.GetFileList())
 | |
|         if 'EDK_TOOLS_PATH' in os.environ:
 | |
|             RootDir = os.environ['EDK_TOOLS_PATH']
 | |
|     if MiscObject:
 | |
|         FileList += MiscObject.GetFileList()
 | |
|     for FileObject in FileList:
 | |
|         FileNum += 1
 | |
|         if FileNum > ToolFileNum:
 | |
|             #
 | |
|             # Misc files, root should be changed to WORKSPACE
 | |
|             #
 | |
|             RootDir = WorkspaceDir
 | |
|         File = ConvertPath(FileObject.GetURI())
 | |
|         ToFile = os.path.normpath(os.path.join(RootDir, File))
 | |
|         if os.path.exists(ToFile):
 | |
|             Logger.Info( ST.WRN_FILE_EXISTED % ToFile )
 | |
|             #
 | |
|             # ask for user input the new file name
 | |
|             #
 | |
|             Logger.Info( ST.MSG_NEW_FILE_NAME)
 | |
|             Input = stdin.readline()
 | |
|             Input = Input.replace('\r', '').replace('\n', '')
 | |
|             OrigPath = os.path.split(ToFile)[0]
 | |
|             ToFile = os.path.normpath(os.path.join(OrigPath, Input))
 | |
|         FromFile = os.path.join(FileObject.GetURI())
 | |
|         Md5Sum = InstallFile(ContentZipFile, FromFile, ToFile, DistPkg.Header.ReadOnly, FileObject.GetExecutable())
 | |
|         DistPkg.FileList.append((ToFile, Md5Sum))
 | |
| 
 | |
| ## Tool entrance method
 | |
| #
 | |
| # This method mainly dispatch specific methods per the command line options.
 | |
| # If no error found, return zero value so the caller of this tool can know
 | |
| # if it's executed successfully or not.
 | |
| #
 | |
| # @param  Options: command Options
 | |
| #
 | |
| def Main(Options = None):
 | |
|     ContentZipFile, DistFile = None, None
 | |
| 
 | |
|     try:
 | |
|         DataBase = GlobalData.gDB        
 | |
|         CheckEnvVariable()
 | |
|         WorkspaceDir = GlobalData.gWORKSPACE
 | |
|         if not Options.PackageFile:
 | |
|             Logger.Error("InstallPkg", OPTION_MISSING, ExtraData=ST.ERR_SPECIFY_PACKAGE)
 | |
|         
 | |
|         #
 | |
|         # unzip dist.pkg file
 | |
|         #
 | |
|         DistPkg, Dep, ContentZipFile, DpPkgFileName = UnZipDp(WorkspaceDir, Options, DataBase)
 | |
| 
 | |
|         #
 | |
|         # PackageList, ModuleList record the information for the meta-data
 | |
|         # files that need to be generated later
 | |
|         #
 | |
|         PackageList = []
 | |
|         ModuleList = []
 | |
|         DistPkg.PackageSurfaceArea = GetPackageList(DistPkg, Dep, WorkspaceDir, Options, 
 | |
|                                                     ContentZipFile, ModuleList, PackageList)
 | |
| 
 | |
|         DistPkg.ModuleSurfaceArea = GetModuleList(DistPkg, Dep, WorkspaceDir, ContentZipFile, ModuleList)       
 | |
|         
 | |
|         
 | |
|         GenToolMisc(DistPkg, WorkspaceDir, ContentZipFile)
 | |
|         
 | |
|         #
 | |
|         # copy "Distribution File" to directory $(WORKSPACE)/conf/upt
 | |
|         #
 | |
|         DistFileName = os.path.split(DpPkgFileName)[1]
 | |
|         DestDir = os.path.normpath(os.path.join(WorkspaceDir, GlobalData.gUPT_DIR))
 | |
|         CreateDirectory(DestDir)
 | |
|         DestFile = os.path.normpath(os.path.join(DestDir, DistFileName))
 | |
|         if os.path.exists(DestFile):
 | |
|             FileName, Ext = os.path.splitext(DistFileName)
 | |
|             NewFileName = FileName + '_' + DistPkg.Header.GetGuid() + '_' + DistPkg.Header.GetVersion() + '.' + Ext
 | |
|             DestFile = os.path.normpath(os.path.join(DestDir, NewFileName))
 | |
|             if os.path.exists(DestFile):
 | |
|                 #
 | |
|                 # ask for user input the new file name
 | |
|                 #
 | |
|                 Logger.Info( ST.MSG_NEW_FILE_NAME_FOR_DIST)
 | |
|                 Input = stdin.readline()
 | |
|                 Input = Input.replace('\r', '').replace('\n', '')
 | |
|                 DestFile = os.path.normpath(os.path.join(DestDir, Input))
 | |
|         copyfile(DpPkgFileName, DestFile)
 | |
|         NewDpPkgFileName = DestFile[DestFile.find(DestDir) + len(DestDir) + 1:]
 | |
| 
 | |
|         #
 | |
|         # update database
 | |
|         #
 | |
|         Logger.Quiet(ST.MSG_UPDATE_PACKAGE_DATABASE)
 | |
|         DataBase.AddDPObject(DistPkg, NewDpPkgFileName, DistFileName, 
 | |
|                        DistPkg.Header.RePackage)
 | |
|         
 | |
|         ReturnCode = 0
 | |
|         
 | |
|     except FatalError, XExcept:
 | |
|         ReturnCode = XExcept.args[0]
 | |
|         if Logger.GetLevel() <= Logger.DEBUG_9:
 | |
|             Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(),
 | |
|                 platform) + format_exc())
 | |
|     except KeyboardInterrupt:
 | |
|         ReturnCode = ABORT_ERROR
 | |
|         if Logger.GetLevel() <= Logger.DEBUG_9:
 | |
|             Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(),
 | |
|                 platform) + format_exc())
 | |
|     except:
 | |
|         ReturnCode = CODE_ERROR
 | |
|         Logger.Error(
 | |
|                     "\nInstallPkg",
 | |
|                     CODE_ERROR,
 | |
|                     ST.ERR_UNKNOWN_FATAL_INSTALL_ERR % Options.PackageFile,
 | |
|                     ExtraData=ST.MSG_SEARCH_FOR_HELP,
 | |
|                     RaiseError=False
 | |
|                     )
 | |
|         Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(),
 | |
|             platform) + format_exc())
 | |
| 
 | |
|     finally:
 | |
|         Logger.Quiet(ST.MSG_REMOVE_TEMP_FILE_STARTED)
 | |
|         if DistFile:
 | |
|             DistFile.Close()
 | |
|         if ContentZipFile:
 | |
|             ContentZipFile.Close()
 | |
|         if GlobalData.gUNPACK_DIR:
 | |
|             rmtree(GlobalData.gUNPACK_DIR)
 | |
|             GlobalData.gUNPACK_DIR = None
 | |
|         Logger.Quiet(ST.MSG_REMOVE_TEMP_FILE_DONE)
 | |
| 
 | |
|     if ReturnCode == 0:
 | |
|         Logger.Quiet(ST.MSG_FINISH)
 | |
|     
 | |
|     return ReturnCode
 | |
| 
 | |
| ## InstallModuleContent method
 | |
| #
 | |
| # If this is standalone module, then Package should be none,
 | |
| # ModulePath should be ''
 | |
| #   @param  FromPath: FromPath
 | |
| #   @param  NewPath: NewPath
 | |
| #   @param  ModulePath: ModulePath
 | |
| #   @param  Module: Module
 | |
| #   @param  ContentZipFile: ContentZipFile
 | |
| #   @param  WorkspaceDir: WorkspaceDir
 | |
| #   @param  ModuleList: ModuleList
 | |
| #   @param  Package: Package
 | |
| #
 | |
| def InstallModuleContent(FromPath, NewPath, ModulePath, Module, ContentZipFile,
 | |
|     WorkspaceDir, ModuleList, Package = None, ReadOnly = False):
 | |
|     
 | |
|     if NewPath.startswith("\\") or NewPath.startswith("/"):
 | |
|         NewPath = NewPath[1:]
 | |
|     
 | |
|     if not IsValidInstallPath(NewPath):
 | |
|         Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%NewPath) 
 | |
|            
 | |
|     NewModuleFullPath = os.path.normpath(os.path.join(WorkspaceDir, NewPath,
 | |
|         ConvertPath(ModulePath)))
 | |
|     Module.SetFullPath(os.path.normpath(os.path.join(NewModuleFullPath,
 | |
|         ConvertPath(Module.GetName()) + '.inf')))
 | |
|     Module.FileList = []
 | |
|     
 | |
|     for MiscFile in Module.GetMiscFileList():
 | |
|         if not MiscFile:
 | |
|             continue
 | |
|         for Item in MiscFile.GetFileList():
 | |
|             File = Item.GetURI()
 | |
|             if File.startswith("\\") or File.startswith("/"):
 | |
|                 File = File[1:]
 | |
|             
 | |
|             if not IsValidInstallPath(File):
 | |
|                 Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%File)
 | |
|                       
 | |
|             FromFile = os.path.join(FromPath, ModulePath, File)
 | |
|             Executable = Item.GetExecutable()            
 | |
|             ToFile = os.path.normpath(os.path.join(NewModuleFullPath, ConvertPath(File)))
 | |
|             Md5Sum = InstallFile(ContentZipFile, FromFile, ToFile, ReadOnly, Executable)
 | |
|             if Package and ((ToFile, Md5Sum) not in Package.FileList):
 | |
|                 Package.FileList.append((ToFile, Md5Sum))
 | |
|             elif Package:
 | |
|                 continue
 | |
|             elif (ToFile, Md5Sum) not in Module.FileList:
 | |
|                 Module.FileList.append((ToFile, Md5Sum))
 | |
|     for Item in Module.GetSourceFileList():
 | |
|         File = Item.GetSourceFile()
 | |
|         if File.startswith("\\") or File.startswith("/"):
 | |
|             File = File[1:]
 | |
|             
 | |
|         if not IsValidInstallPath(File):
 | |
|             Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%File) 
 | |
|                                
 | |
|         FromFile = os.path.join(FromPath, ModulePath, File)
 | |
|         ToFile = os.path.normpath(os.path.join(NewModuleFullPath, ConvertPath(File)))
 | |
|         Md5Sum = InstallFile(ContentZipFile, FromFile, ToFile, ReadOnly)
 | |
|         if Package and ((ToFile, Md5Sum) not in Package.FileList):
 | |
|             Package.FileList.append((ToFile, Md5Sum))
 | |
|         elif Package:
 | |
|             continue
 | |
|         elif (ToFile, Md5Sum) not in Module.FileList:
 | |
|             Module.FileList.append((ToFile, Md5Sum))
 | |
|     for Item in Module.GetBinaryFileList():
 | |
|         FileNameList = Item.GetFileNameList()
 | |
|         for FileName in FileNameList:              
 | |
|             File = FileName.GetFilename()          
 | |
|             if File.startswith("\\") or File.startswith("/"):
 | |
|                 File = File[1:]
 | |
|                 
 | |
|             if not IsValidInstallPath(File):
 | |
|                 Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%File)
 | |
| 
 | |
|             FromFile = os.path.join(FromPath, ModulePath, File)
 | |
|             ToFile = os.path.normpath(os.path.join(NewModuleFullPath, ConvertPath(File)))
 | |
|             Md5Sum = InstallFile(ContentZipFile, FromFile, ToFile, ReadOnly)       
 | |
|             if Package and ((ToFile, Md5Sum) not in Package.FileList):
 | |
|                 Package.FileList.append((ToFile, Md5Sum))
 | |
|             elif Package:
 | |
|                 continue
 | |
|             elif (ToFile, Md5Sum) not in Module.FileList:
 | |
|                 Module.FileList.append((ToFile, Md5Sum))
 | |
|     
 | |
|     InstallModuleContentZipFile(ContentZipFile, FromPath, ModulePath, WorkspaceDir, NewPath, Module, Package, ReadOnly,
 | |
|                                 ModuleList)
 | |
| 
 | |
| ## InstallModuleContentZipFile
 | |
| #
 | |
| # InstallModuleContentZipFile
 | |
| #
 | |
| def InstallModuleContentZipFile(ContentZipFile, FromPath, ModulePath, WorkspaceDir, NewPath, Module, Package, ReadOnly,
 | |
|                                 ModuleList):
 | |
|     #
 | |
|     # Extract other files under current module path in content Zip file but not listed in the description 
 | |
|     #
 | |
|     if ContentZipFile:
 | |
|         for FileName in ContentZipFile.GetZipFile().namelist():
 | |
|             FileName = os.path.normpath(FileName)
 | |
|             CheckPath = os.path.normpath(os.path.join(FromPath, ModulePath))
 | |
|             if FileUnderPath(FileName, CheckPath):
 | |
|                 if FileName.startswith("\\") or FileName.startswith("/"):
 | |
|                     FileName = FileName[1:]
 | |
|                     
 | |
|                 if not IsValidInstallPath(FileName):
 | |
|                     Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%FileName)
 | |
|                                                    
 | |
|                 FromFile = FileName
 | |
|                 ToFile = os.path.normpath(os.path.join(WorkspaceDir, 
 | |
|                         ConvertPath(FileName.replace(FromPath, NewPath, 1))))
 | |
|                 CheckList = Module.FileList
 | |
|                 if Package:
 | |
|                     CheckList += Package.FileList
 | |
|                 for Item in CheckList:
 | |
|                     if Item[0] == ToFile:
 | |
|                         break
 | |
|                 else:
 | |
|                     Md5Sum = InstallFile(ContentZipFile, FromFile, ToFile, ReadOnly)
 | |
|                     if Package and ((ToFile, Md5Sum) not in Package.FileList):
 | |
|                         Package.FileList.append((ToFile, Md5Sum))
 | |
|                     elif Package:
 | |
|                         continue
 | |
|                     elif (ToFile, Md5Sum) not in Module.FileList:
 | |
|                         Module.FileList.append((ToFile, Md5Sum))            
 | |
|     
 | |
|     ModuleList.append((Module, Package))
 | |
| 
 | |
| ## FileUnderPath
 | |
| #  Check whether FileName started with directory specified by CheckPath 
 | |
| #
 | |
| # @param FileName: the FileName need to be checked
 | |
| # @param CheckPath: the path need to be checked against
 | |
| # @return:  True or False  
 | |
| #
 | |
| def FileUnderPath(FileName, CheckPath):
 | |
|     FileName = FileName.replace('\\', '/')
 | |
|     FileName = os.path.normpath(FileName)
 | |
|     CheckPath = CheckPath.replace('\\', '/')
 | |
|     CheckPath = os.path.normpath(CheckPath)
 | |
|     if FileName.startswith(CheckPath):
 | |
|         RemainingPath = os.path.normpath(FileName.replace(CheckPath, '', 1))
 | |
|         while RemainingPath.startswith('\\') or RemainingPath.startswith('/'):
 | |
|             RemainingPath = RemainingPath[1:]
 | |
|         if FileName == os.path.normpath(os.path.join(CheckPath, RemainingPath)):
 | |
|             return True
 | |
|     
 | |
|     return False
 | |
| 
 | |
| ## InstallFile
 | |
| #  Extract File from Zipfile, set file attribute, and return the Md5Sum
 | |
| #
 | |
| # @return:  True or False  
 | |
| #
 | |
| def InstallFile(ContentZipFile, FromFile, ToFile, ReadOnly, Executable=False):
 | |
|     if not ContentZipFile or not ContentZipFile.UnpackFile(FromFile, ToFile):
 | |
|         Logger.Error("UPT", FILE_NOT_FOUND, ST.ERR_INSTALL_FILE_FROM_EMPTY_CONTENT%FromFile)
 | |
| 
 | |
|     if ReadOnly:
 | |
|         if not Executable:
 | |
|             chmod(ToFile, stat.S_IREAD)
 | |
|         else:
 | |
|             chmod(ToFile, stat.S_IREAD|stat.S_IEXEC)
 | |
|     elif Executable:
 | |
|         chmod(ToFile, stat.S_IREAD|stat.S_IWRITE|stat.S_IEXEC)
 | |
|     else:
 | |
|         chmod(ToFile, stat.S_IREAD|stat.S_IWRITE)
 | |
|                 
 | |
|     Md5Sigature = md5.new(open(str(ToFile), 'rb').read())
 | |
|     Md5Sum = Md5Sigature.hexdigest()
 | |
|     return Md5Sum
 | |
|         
 | |
| ## InstallPackageContent method
 | |
| #
 | |
| #   @param  FromPath: FromPath
 | |
| #   @param  ToPath: ToPath
 | |
| #   @param  Package: Package
 | |
| #   @param  ContentZipFile: ContentZipFile
 | |
| #   @param  Dep: Dep
 | |
| #   @param  WorkspaceDir: WorkspaceDir
 | |
| #   @param  ModuleList: ModuleList
 | |
| #
 | |
| def InstallPackageContent(FromPath, ToPath, Package, ContentZipFile, Dep,
 | |
|     WorkspaceDir, ModuleList, ReadOnly = False):
 | |
|     if Dep:
 | |
|         pass
 | |
|     Package.FileList = []
 | |
|     
 | |
|     if ToPath.startswith("\\") or ToPath.startswith("/"):
 | |
|         ToPath = ToPath[1:]
 | |
|     
 | |
|     if not IsValidInstallPath(ToPath):
 | |
|         Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%ToPath)     
 | |
| 
 | |
|     if FromPath.startswith("\\") or FromPath.startswith("/"):
 | |
|         FromPath = FromPath[1:]
 | |
|     
 | |
|     if not IsValidInstallPath(FromPath):
 | |
|         Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%FromPath)   
 | |
|     
 | |
|     PackageFullPath = os.path.normpath(os.path.join(WorkspaceDir, ToPath))
 | |
|     for MiscFile in Package.GetMiscFileList():
 | |
|         for Item in MiscFile.GetFileList():
 | |
|             FileName = Item.GetURI()
 | |
|             if FileName.startswith("\\") or FileName.startswith("/"):
 | |
|                 FileName = FileName[1:]
 | |
|                 
 | |
|             if not IsValidInstallPath(FileName):
 | |
|                 Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%FileName)
 | |
|                             
 | |
|             FromFile = os.path.join(FromPath, FileName)
 | |
|             Executable = Item.GetExecutable()
 | |
|             ToFile =  (os.path.join(PackageFullPath, ConvertPath(FileName)))
 | |
|             Md5Sum = InstallFile(ContentZipFile, FromFile, ToFile, ReadOnly, Executable)
 | |
|             if (ToFile, Md5Sum) not in Package.FileList:
 | |
|                 Package.FileList.append((ToFile, Md5Sum))
 | |
|     PackageIncludeArchList = [] 
 | |
|     for Item in Package.GetPackageIncludeFileList():
 | |
|         FileName = Item.GetFilePath()
 | |
|         if FileName.startswith("\\") or FileName.startswith("/"):
 | |
|             FileName = FileName[1:]
 | |
|             
 | |
|         if not IsValidInstallPath(FileName):
 | |
|             Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%FileName) 
 | |
|                    
 | |
|         FromFile = os.path.join(FromPath, FileName)
 | |
|         ToFile = os.path.normpath(os.path.join(PackageFullPath, ConvertPath(FileName)))
 | |
|         RetFile = ContentZipFile.UnpackFile(FromFile, ToFile)
 | |
|         if RetFile == '':
 | |
|             #
 | |
|             # a non-exist path in Zipfile will return '', which means an include directory in our case
 | |
|             # save the information for later DEC creation usage and also create the directory
 | |
|             #
 | |
|             PackageIncludeArchList.append([Item.GetFilePath(), Item.GetSupArchList()])
 | |
|             CreateDirectory(ToFile)
 | |
|             continue
 | |
|         if ReadOnly:
 | |
|             chmod(ToFile, stat.S_IREAD)
 | |
|         else:
 | |
|             chmod(ToFile, stat.S_IREAD|stat.S_IWRITE)            
 | |
|         Md5Sigature = md5.new(open(str(ToFile), 'rb').read())
 | |
|         Md5Sum = Md5Sigature.hexdigest()
 | |
|         if (ToFile, Md5Sum) not in Package.FileList:
 | |
|             Package.FileList.append((ToFile, Md5Sum))
 | |
|     Package.SetIncludeArchList(PackageIncludeArchList)
 | |
|     
 | |
|     for Item in Package.GetStandardIncludeFileList():
 | |
|         FileName = Item.GetFilePath()
 | |
|         if FileName.startswith("\\") or FileName.startswith("/"):
 | |
|             FileName = FileName[1:]
 | |
|             
 | |
|         if not IsValidInstallPath(FileName):
 | |
|             Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%FileName) 
 | |
|                     
 | |
|         FromFile = os.path.join(FromPath, FileName)
 | |
|         ToFile = os.path.normpath(os.path.join(PackageFullPath, ConvertPath(FileName)))
 | |
|         Md5Sum = InstallFile(ContentZipFile, FromFile, ToFile, ReadOnly)
 | |
|         if (ToFile, Md5Sum) not in Package.FileList:
 | |
|             Package.FileList.append((ToFile, Md5Sum))
 | |
| 
 | |
|     #
 | |
|     # Update package
 | |
|     #
 | |
|     Package.SetPackagePath(Package.GetPackagePath().replace(FromPath,
 | |
|         ToPath, 1))
 | |
|     Package.SetFullPath(os.path.normpath(os.path.join(PackageFullPath,
 | |
|         ConvertPath(Package.GetName()) + '.dec')))
 | |
| 
 | |
|     #
 | |
|     # Install files in module
 | |
|     #
 | |
|     Module = None
 | |
|     ModuleDict = Package.GetModuleDict()
 | |
|     for ModuleGuid, ModuleVersion, ModulePath in ModuleDict:
 | |
|         Module = ModuleDict[ModuleGuid, ModuleVersion, ModulePath]
 | |
|         InstallModuleContent(FromPath, ToPath, ModulePath, Module,
 | |
|             ContentZipFile, WorkspaceDir, ModuleList, Package, ReadOnly)
 | |
| 
 | |
| ## GetDPFile method
 | |
| #
 | |
| #   @param  ZipFile: A ZipFile
 | |
| #
 | |
| def GetDPFile(ZipFile):
 | |
|     ContentFile = ''
 | |
|     DescFile = ''
 | |
|     for FileName in ZipFile.namelist():
 | |
|         if FileName.endswith('.content'):
 | |
|             if not ContentFile:
 | |
|                 ContentFile = FileName
 | |
|                 continue
 | |
|         elif FileName.endswith('.pkg'):
 | |
|             if not DescFile:
 | |
|                 DescFile = FileName
 | |
|                 continue
 | |
|         else:
 | |
|             continue
 | |
|         
 | |
|         Logger.Error("PackagingTool", FILE_TYPE_MISMATCH,
 | |
|             ExtraData=ST.ERR_DIST_FILE_TOOMANY)
 | |
|     if not DescFile or not ContentFile:
 | |
|         Logger.Error("PackagingTool", FILE_UNKNOWN_ERROR,
 | |
|             ExtraData=ST.ERR_DIST_FILE_TOOFEW)
 | |
|     return DescFile, ContentFile
 | |
| 
 |