summaryrefslogtreecommitdiff
path: root/BaseTools/Source/Python/PackagingTool/InstallPkg.py
diff options
context:
space:
mode:
Diffstat (limited to 'BaseTools/Source/Python/PackagingTool/InstallPkg.py')
-rw-r--r--BaseTools/Source/Python/PackagingTool/InstallPkg.py309
1 files changed, 309 insertions, 0 deletions
diff --git a/BaseTools/Source/Python/PackagingTool/InstallPkg.py b/BaseTools/Source/Python/PackagingTool/InstallPkg.py
new file mode 100644
index 0000000000..963a654ea1
--- /dev/null
+++ b/BaseTools/Source/Python/PackagingTool/InstallPkg.py
@@ -0,0 +1,309 @@
+## @file
+# Install distribution package.
+#
+# Copyright (c) 2007, Intel Corporation
+# All rights reserved. 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.
+#
+
+##
+# Import Modules
+#
+import os
+import sys
+import glob
+import shutil
+import traceback
+import platform
+from optparse import OptionParser
+
+import Common.EdkLogger as EdkLogger
+from Common.BuildToolError import *
+from Common.Misc import *
+from Common.XmlParser import *
+from Common.InfClassObjectLight import Inf
+from Common.DecClassObjectLight import Dec
+
+from PackageFile import *
+from IpiDb import *
+from DependencyRules import *
+import md5
+
+# Version and Copyright
+VersionNumber = "0.1"
+__version__ = "%prog Version " + VersionNumber
+__copyright__ = "Copyright (c) 2008, Intel Corporation All rights reserved."
+
+## Check environment variables
+#
+# Check environment variables that must be set for build. Currently they are
+#
+# WORKSPACE The directory all packages/platforms start from
+# EDK_TOOLS_PATH The directory contains all tools needed by the build
+# PATH $(EDK_TOOLS_PATH)/Bin/<sys> must be set in PATH
+#
+# If any of above environment variable is not set or has error, the build
+# will be broken.
+#
+def CheckEnvVariable():
+ # check WORKSPACE
+ if "WORKSPACE" not in os.environ:
+ EdkLogger.error("InstallPkg", ATTRIBUTE_NOT_AVAILABLE, "Environment variable not found",
+ ExtraData="WORKSPACE")
+
+ WorkspaceDir = os.path.normpath(os.environ["WORKSPACE"])
+ if not os.path.exists(WorkspaceDir):
+ EdkLogger.error("InstallPkg", FILE_NOT_FOUND, "WORKSPACE doesn't exist", ExtraData="%s" % WorkspaceDir)
+ elif ' ' in WorkspaceDir:
+ EdkLogger.error("InstallPkg", FORMAT_NOT_SUPPORTED, "No space is allowed in WORKSPACE path",
+ ExtraData=WorkspaceDir)
+ os.environ["WORKSPACE"] = WorkspaceDir
+
+## Parse command line options
+#
+# Using standard Python module optparse to parse command line option of this tool.
+#
+# @retval Opt A optparse.Values object containing the parsed options
+# @retval Args Target of build command
+#
+def MyOptionParser():
+ UsageString = "%prog -i <distribution_package> [-t] [-f] [-q | -v] [-h]"
+
+ Parser = OptionParser(description=__copyright__,version=__version__,prog="InstallPkg",usage=UsageString)
+
+ Parser.add_option("-?", action="help", help="show this help message and exit")
+
+ Parser.add_option("-i", "--distribution-package", action="store", type="string", dest="PackageFile",
+ help="The distribution package to be installed")
+
+ Parser.add_option("-t", "--install-tools", action="store_true", type=None, dest="Tools",
+ help="Specify it to install tools or ignore the tools of the distribution package.")
+
+ Parser.add_option("-f", "--misc-files", action="store_true", type=None, dest="MiscFiles",
+ help="Specify it to install misc file or ignore the misc files of the distribution package.")
+
+ Parser.add_option("-q", "--quiet", action="store_const", dest="LogLevel", const=EdkLogger.QUIET,
+ help="Disable all messages except FATAL ERRORS.")
+
+ Parser.add_option("-v", "--verbose", action="store_const", dest="LogLevel", const=EdkLogger.VERBOSE,
+ help="Turn on verbose output")
+
+ Parser.add_option("-d", "--debug", action="store", type="int", dest="LogLevel",
+ help="Enable debug messages at specified level.")
+
+ Parser.set_defaults(LogLevel=EdkLogger.INFO)
+
+ (Opt, Args)=Parser.parse_args()
+
+ return Opt
+
+def InstallNewPackage(WorkspaceDir, Path):
+ FullPath = os.path.normpath(os.path.join(WorkspaceDir, Path))
+ if os.path.exists(FullPath):
+ print "Directory [%s] already exists, please select another location, press [Enter] with no input to quit:" %Path
+ Input = sys.stdin.readline()
+ Input = Input.replace('\r', '').replace('\n', '')
+ if Input == '':
+ EdkLogger.error("InstallPkg", UNKNOWN_ERROR, "User interrupt")
+ Input = Input.replace('\r', '').replace('\n', '')
+ return InstallNewPackage(WorkspaceDir, Input)
+ else:
+ return Path
+
+def InstallNewFile(WorkspaceDir, File):
+ FullPath = os.path.normpath(os.path.join(WorkspaceDir, File))
+ if os.path.exists(FullPath):
+ print "File [%s] already exists, please select another path, press [Enter] with no input to quit:" %File
+ Input = sys.stdin.readline()
+ Input = Input.replace('\r', '').replace('\n', '')
+ if Input == '':
+ EdkLogger.error("InstallPkg", UNKNOWN_ERROR, "User interrupt")
+ Input = Input.replace('\r', '').replace('\n', '')
+ return InstallNewFile(WorkspaceDir, Input)
+ else:
+ return File
+
+## 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.
+#
+# @retval 0 Tool was successful
+# @retval 1 Tool failed
+#
+def Main():
+ EdkLogger.Initialize()
+ Options = None
+ DistFileName = 'dist.pkg'
+ ContentFileName = 'content.zip'
+ DistFile, ContentZipFile, UnpackDir = None, None, None
+
+ Options = MyOptionParser()
+ try:
+ if Options.LogLevel < EdkLogger.DEBUG_9:
+ EdkLogger.SetLevel(Options.LogLevel + 1)
+ else:
+ EdkLogger.SetLevel(Options.LogLevel)
+
+ CheckEnvVariable()
+ WorkspaceDir = os.environ["WORKSPACE"]
+ if not Options.PackageFile:
+ EdkLogger.error("InstallPkg", OPTION_NOT_SUPPORTED, ExtraData="Must specify one distribution package")
+
+ # unzip dist.pkg file
+ EdkLogger.quiet("Unzipping and parsing distribution package XML file ... ")
+ DistFile = PackageFile(Options.PackageFile)
+ UnpackDir = os.path.normpath(os.path.join(WorkspaceDir, ".tmp"))
+ DistPkgFile = DistFile.UnpackFile(DistFileName, os.path.normpath(os.path.join(UnpackDir, DistFileName)))
+ if not DistPkgFile:
+ EdkLogger.error("InstallPkg", FILE_NOT_FOUND, "File [%s] is broken in distribution package" %DistFileName)
+
+ # Generate distpkg
+ DistPkgObj = DistributionPackageXml()
+ DistPkg = DistPkgObj.FromXml(DistPkgFile)
+
+ # prepare check dependency
+ Db = IpiDatabase(os.path.normpath(os.path.join(WorkspaceDir, "Conf/DistributionPackageDatabase.db")))
+ Db.InitDatabase()
+ Dep = DependencyRules(Db)
+
+ # Check distribution package exist
+ if Dep.CheckDpExists(DistPkg.Header.Guid, DistPkg.Header.Version):
+ EdkLogger.error("InstallPkg", UNKNOWN_ERROR, "This distribution package has been installed", ExtraData=DistPkg.Header.Name)
+
+ # unzip contents.zip file
+ ContentFile = DistFile.UnpackFile(ContentFileName, os.path.normpath(os.path.join(UnpackDir, ContentFileName)))
+ ContentZipFile = PackageFile(ContentFile)
+ if not ContentFile:
+ EdkLogger.error("InstallPkg", FILE_NOT_FOUND, "File [%s] is broken in distribution package" %ContentFileName)
+
+ # verify MD5 signature
+ Md5Sigature = md5.new(open(ContentFile).read())
+ if DistPkg.Header.Signature != Md5Sigature.hexdigest():
+ EdkLogger.error("InstallPkg", FILE_CHECKSUM_FAILURE, ExtraData=ContentFile)
+
+ # Check package exist and install
+ for Guid,Version,Path in DistPkg.PackageSurfaceArea:
+ PackagePath = os.path.dirname(Path)
+ NewPackagePath = PackagePath
+ Package = DistPkg.PackageSurfaceArea[Guid,Version,Path]
+ EdkLogger.info("Installing package ... %s" % Package.PackageHeader.Name)
+ if Dep.CheckPackageExists(Guid, Version):
+ EdkLogger.quiet("Package [%s] has been installed" %Path)
+ NewPackagePath = InstallNewPackage(WorkspaceDir, PackagePath)
+ Package.FileList = []
+ for Item in Package.MiscFiles.Files:
+ FromFile = os.path.join(PackagePath, Item.Filename)
+ ToFile = os.path.normpath(os.path.join(WorkspaceDir, NewPackagePath, Item.Filename))
+ ContentZipFile.UnpackFile(FromFile, ToFile)
+ Package.FileList.append(ToFile)
+
+ # Update package
+ Package.PackageHeader.CombinePath = Package.PackageHeader.CombinePath.replace(PackagePath, NewPackagePath, 1)
+ # Update modules of package
+ Module = None
+ for ModuleGuid, ModuleVersion, ModulePath in Package.Modules:
+ Module = Package.Modules[ModuleGuid, ModuleVersion, ModulePath]
+ NewModulePath = ModulePath.replace(PackagePath, NewPackagePath, 1)
+ del Package.Modules[ModuleGuid, ModuleVersion, ModulePath]
+ Package.Modules[ModuleGuid, ModuleVersion, NewModulePath] = Module
+ del DistPkg.PackageSurfaceArea[Guid,Version,Path]
+ DistPkg.PackageSurfaceArea[Guid,Version,Package.PackageHeader.CombinePath] = Package
+
+# SaveFileOnChange(os.path.join(Options.InstallDir, ModulePath, Module.Header.Name, ".inf"), Inf.ModuleToInf(Module), False)
+# EdkLogger.info("Installing package ... %s" % Package.Header.Name)
+# shutil.copytree(os.path.join(ContentFileDir, Path), Options.InstallDir)
+# SaveFileOnChange(os.path.join(Options.InstallDir, Path, Package.Header.Name, ".dec"), Dec.PackageToDec(Package), False)
+
+ # Check module exist and install
+ Module = None
+ for Guid,Version,Path in DistPkg.ModuleSurfaceArea:
+ ModulePath = os.path.dirname(Path)
+ NewModulePath = ModulePath
+ Module = DistPkg.ModuleSurfaceArea[Guid,Version,Path]
+ EdkLogger.info("Installing module ... %s" % Module.ModuleHeader.Name)
+ if Dep.CheckModuleExists(Guid, Version):
+ EdkLogger.quiet("Module [%s] has been installed" %Path)
+ NewModulePath = InstallNewPackage(WorkspaceDir, ModulePath)
+ Module.FileList = []
+ for Item in Module.MiscFiles.Files:
+ ModulePath = ModulePath[os.path.normpath(ModulePath).rfind(os.path.normpath('/'))+1:]
+ FromFile = os.path.join(ModulePath, Item.Filename)
+ ToFile = os.path.normpath(os.path.join(WorkspaceDir, NewModulePath, Item.Filename))
+ ContentZipFile.UnpackFile(FromFile, ToFile)
+ Module.FileList.append(ToFile)
+
+# EdkLogger.info("Installing module ... %s" % Module.Header.Name)
+# shutil.copytree(os.path.join(ContentFileDir, Path), Options.InstallDir)
+# SaveFileOnChange(os.path.join(Options.InstallDir, Path, Module.Header.Name, ".inf"), Inf.ModuleToInf(Module), False)
+
+ # Update module
+ Module.ModuleHeader.CombinePath = Module.ModuleHeader.CombinePath.replace(os.path.dirname(Path), NewModulePath, 1)
+ del DistPkg.ModuleSurfaceArea[Guid,Version,Path]
+ DistPkg.ModuleSurfaceArea[Guid,Version,Module.ModuleHeader.CombinePath] = Module
+#
+#
+# for Guid,Version,Path in DistPkg.PackageSurfaceArea:
+# print Guid,Version,Path
+# for item in DistPkg.PackageSurfaceArea[Guid,Version,Path].FileList:
+# print item
+# for Guid,Version,Path in DistPkg.ModuleSurfaceArea:
+# print Guid,Version,Path
+# for item in DistPkg.ModuleSurfaceArea[Guid,Version,Path].FileList:
+# print item
+
+ if Options.Tools:
+ EdkLogger.info("Installing tools ... ")
+ for File in DistPkg.Tools.Files:
+ FromFile = File.Filename
+ ToFile = InstallNewFile(WorkspaceDir, FromFile)
+ ContentZipFile.UnpackFile(FromFile, ToFile)
+ if Options.MiscFiles:
+ EdkLogger.info("Installing misc files ... ")
+ for File in DistPkg.MiscellaneousFiles.Files:
+ FromFile = File.Filename
+ ToFile = InstallNewFile(WorkspaceDir, FromFile)
+ ContentZipFile.UnpackFile(FromFile, ToFile)
+
+ # update database
+ EdkLogger.quiet("Update Distribution Package Database ...")
+ Db.AddDPObject(DistPkg)
+
+ except FatalError, X:
+ if Options and Options.LogLevel < EdkLogger.DEBUG_9:
+ EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())
+ ReturnCode = X.args[0]
+ except KeyboardInterrupt:
+ ReturnCode = ABORT_ERROR
+ if Options and Options.LogLevel < EdkLogger.DEBUG_9:
+ EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())
+ except:
+ EdkLogger.error(
+ "\nInstallPkg",
+ CODE_ERROR,
+ "Unknown fatal error when installing [%s]" % Options.PackageFile,
+ ExtraData="\n(Please send email to dev@buildtools.tianocore.org for help, attaching following call stack trace!)\n",
+ RaiseError=False
+ )
+ EdkLogger.quiet("(Python %s on %s) " % (platform.python_version(), sys.platform) + traceback.format_exc())
+ ReturnCode = CODE_ERROR
+ finally:
+ EdkLogger.quiet("Removing temp files ... ")
+ if DistFile:
+ DistFile.Close()
+ if ContentZipFile:
+ ContentZipFile.Close()
+ if UnpackDir:
+ shutil.rmtree(UnpackDir)
+
+ EdkLogger.quiet("DONE")
+ Progressor.Abort()
+
+if __name__ == '__main__':
+ sys.exit(Main())