Adding several dependency checks for far installation. Redoing the XML output.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2299 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
bbahnsen 2007-01-24 18:14:09 +00:00
parent 92a154063a
commit 312ffece7b
3 changed files with 149 additions and 149 deletions

View File

@ -7,11 +7,18 @@ import os, sys, getopt, string, xml.dom.minidom, zipfile, md5
from XmlRoutines import * from XmlRoutines import *
from WorkspaceRoutines import * from WorkspaceRoutines import *
verbose = False class Flags:
force = False """Keep track of some command line flags and operating modes."""
def __init__(self):
self.verbose = False
self.force = False
self.reinstall = False
class Database: class Database:
"""This class encapsulates the FrameworkDatabase file for the workspace we
are operating on."""
def __init__(self, filename="Tools/Conf/FrameworkDatabase.db"): def __init__(self, filename="Tools/Conf/FrameworkDatabase.db"):
# First try to get a lock file. # First try to get a lock file.
@ -35,13 +42,13 @@ class Database:
for spdfile in XmlList(self.dom, "/FrameworkDatabase/PackageList/Filename"): for spdfile in XmlList(self.dom, "/FrameworkDatabase/PackageList/Filename"):
filename = str(XmlElementData(spdfile)) filename = str(XmlElementData(spdfile))
spd = XmlParseFileSection(inWorkspace(filename), "SpdHeader") spd = XmlParseFileSection(inWorkspace(filename), "SpdHeader")
self.installedPackages[XmlElement(spd, "/SpdHeader/GuidValue"), XmlElement(spd, "/SpdHeader/Version")] = \ self.installedPackages[GetSpdGuidVersion(spd, 1)] = \
XmlElement(spd, "/SpdHeader/PackageName") XmlElement(spd, "/SpdHeader/PackageName")
for fpdfile in XmlList(self.dom, "/FrameworkDatabase/PlatformList/Filename"): for fpdfile in XmlList(self.dom, "/FrameworkDatabase/PlatformList/Filename"):
filename = str(XmlElementData(fpdfile)) filename = str(XmlElementData(fpdfile))
fpd = XmlParseFileSection(inWorkspace(filename), "PlatformHeader") fpd = XmlParseFileSection(inWorkspace(filename), "PlatformHeader")
self.installedPlatforms[XmlElement(fpd, "/PlatformHeader/GuidValue"), XmlElement(fpd, "/PlatformHeader/Version") ] = \ self.installedPlatforms[GetFpdGuidVersion(fpd, 1)] = \
XmlElement(fpd, "/PlatformHeader/PlatformName") XmlElement(fpd, "/PlatformHeader/PlatformName")
for farfile in XmlList(self.dom, "/FrameworkDatabase/FarList/Filename"): for farfile in XmlList(self.dom, "/FrameworkDatabase/FarList/Filename"):
@ -80,22 +87,19 @@ class Database:
return self.installedFars.has_key(farguid) return self.installedFars.has_key(farguid)
def AddPackage(self, f): def AddPackage(self, f):
filename = self.dom.createElement("Filename") """Put this package in the database"""
filename.appendChild(self.dom.createTextNode(f)) XmlAppendChildElement(self.packageList, "Filename", f)
self.packageList.appendChild(filename)
def AddPlatform(self, f): def AddPlatform(self, f):
filename = self.dom.createElement("Filename") """Put this platform in the database"""
filename.appendChild(self.dom.createTextNode(f)) XmlAppendChildElement(self.platformList, "Filename", f)
self.platformList.appendChild(filename)
def AddFar(self, f, guid=""): def AddFar(self, f, guid=""):
filename = self.dom.createElement("Filename") """Put this far in the database"""
filename.setAttribute("FarGuid", guid) XmlAppendChildElement(self.farList, "Filename", f, {"FarGuid":guid} )
filename.appendChild(self.dom.createTextNode(f))
self.farList.appendChild(filename)
def Write(self): def Write(self):
"""Save the Xml tree out to the file."""
if True: if True:
XmlSaveFile(self.dom, self.DBFile) XmlSaveFile(self.dom, self.DBFile)
else: else:
@ -103,9 +107,9 @@ class Database:
f.write(self.dom.toprettyxml(2*" ")) f.write(self.dom.toprettyxml(2*" "))
f.close() f.close()
def ExtractFile(zip, file, workspaceLocation=""): def ExtractFile(zip, file, defaultDir="", workspaceLocation="", md5sum=""):
"""Unzip a file."""
if verbose: if flags.verbose:
print "Extracting ", file print "Extracting ", file
destFile = os.path.join(inWorkspace(workspaceLocation), str(file)) destFile = os.path.join(inWorkspace(workspaceLocation), str(file))
@ -114,25 +118,37 @@ def ExtractFile(zip, file, workspaceLocation=""):
mkdir(destDir) mkdir(destDir)
f = open(destFile, "w") f = open(destFile, "w")
f.write(zip.read(file)) contents = zip.read(os.path.join(defaultDir,file))
if md5sum and (md5.md5(contents).hexdigest() != md5sum):
print "Error: The md5 sum does not match on file %s." % file
f.write(contents)
f.close() f.close()
def GetFpdGuidVersion(Dom): def GetFpdGuidVersion(Dom, strip=0):
"""Get the Guid and version of the fpd from a dom object.""" """Get the Guid and version of the fpd from a dom object."""
return XmlElement(Dom, "/PlatformSurfaceArea/PlatformHeader/GuidValue"), \ gpath = ["PlatformSurfaceArea", "PlatformHeader", "GuidValue"]
XmlElement(Dom, "/PlatformSurfaceArea/PlatformHeader/Version") vpath = ["PlatformSurfaceArea", "PlatformHeader", "Version"]
def GetSpdGuidVersion(Dom): return string.lower(XmlElement(Dom, "/".join(gpath[strip:]))), \
XmlElement(Dom, "/".join(vpath[strip:]))
def GetSpdGuidVersion(Dom, strip=0):
"""Get the Guid and version of the spd from a dom object.""" """Get the Guid and version of the spd from a dom object."""
return XmlElement(Dom, "/PackageSurfaceArea/SpdHeader/GuidValue"), \ gpath = ["PackageSurfaceArea", "SpdHeader", "GuidValue"]
XmlElement(Dom, "/PackageSurfaceArea/SpdHeader/Version") vpath = ["PackageSurfaceArea", "SpdHeader", "Version"]
return string.lower(XmlElement(Dom, "/".join(gpath[strip:]))), \
XmlElement(Dom, "/".join(vpath[strip:]))
def InstallFar(farfile, workspaceLocation=""): def InstallFar(farfile, workspaceLocation=""):
"""Unpack the far an install it in the workspace. We need to adhere to the
rules of far handling."""
far = zipfile.ZipFile(farfile, "r") far = zipfile.ZipFile(farfile, "r")
# Use this list to make sure we get everything from the far. # Use this list to make sure we get everything from the far.
@ -151,21 +167,21 @@ def InstallFar(farfile, workspaceLocation=""):
# Check the packages # Check the packages
for farPackage in XmlList(manifest, "/FrameworkArchiveManifest/FarPackageList/FarPackage/FarFilename"): for farPackage in XmlList(manifest, "/FrameworkArchiveManifest/FarPackageList/FarPackage/FarFilename"):
spdfile = str(XmlElementData(farPackage)) spdfile = str(XmlElementData(farPackage))
spd = XmlParseString(far.read(spdfile)) spd = XmlParseStringSection(far.read(spdfile), "SpdHeader")
packageGV = GetSpdGuidVersion(spd) packageGV = GetSpdGuidVersion(spd, 1)
if fdb.HasPackage(packageGV): if fdb.HasPackage(packageGV):
print "Error: This package is already installed: ", spdfile if not flags.reinstall:
installError = True print "Error: This package is already installed: ", spdfile
installError = True
# Build up a list of the package guid versions that this far is bringing in. # Build up a list of the package guid versions that this far is bringing in.
# This is needed to satisfy dependencies of msas that are in the other packages of # This is needed to satisfy dependencies of msas that are in the other packages of
# this far. # this far.
farSpds.append(packageGV) farSpds.append(packageGV)
spdDoms.append(spd) spdDoms.append((spd, spdfile))
for spd in spdDoms: for spd, spdfile in spdDoms:
# Now we need to get a list of every msa in this spd and check the package dependencies. # Now we need to get a list of every msa in this spd and check the package dependencies.
for msafile in XmlList(spd, "/PackageSurfaceArea/MsaFiles/Filename"): for msafile in XmlList(spd, "/PackageSurfaceArea/MsaFiles/Filename"):
msafilePath = str(os.path.join(os.path.dirname(spdfile), XmlElementData(msafile))) msafilePath = str(os.path.join(os.path.dirname(spdfile), XmlElementData(msafile)))
@ -176,29 +192,52 @@ def InstallFar(farfile, workspaceLocation=""):
guid = package.getAttribute("PackageGuid") guid = package.getAttribute("PackageGuid")
version = package.getAttribute("PackageVersion") version = package.getAttribute("PackageVersion")
# Does anyone provide this package?
if not fdb.HasPackage((guid, version)) and not (guid, version) in farSpds: if not fdb.HasPackage((guid, version)) and not (guid, version) in farSpds:
print "The module %s depends on the package guid % version %s, which is not installed in the workspace." \ print ("Error: The module %s depends on the package guid %s version %s, which " + \
% (msafilePath, guid, version) "is not installed in the workspace, nor is it provided by this far.") \
% (msafilePath, guid, version)
installError = True installError = True
# Check the platforms # Check the platforms
for farPlatform in XmlList(manifest, "/FrameworkArchiveManifest/FarPlatformList/FarPlatform/FarFilename"): for farPlatform in XmlList(manifest, "/FrameworkArchiveManifest/FarPlatformList/FarPlatform/FarFilename"):
fpdfile = str(XmlElementData(farPlatform)) fpdfile = str(XmlElementData(farPlatform))
fpd = XmlParseString(far.read(fpdfile)) fpd = XmlParseString(far.read(fpdfile))
if fdb.HasPlatform(GetFpdGuidVersion(fpd)): if fdb.HasPlatform(GetFpdGuidVersion(fpd, 0)):
print "Error: This platform is already installed: ", fpdfile if not flags.reinstall:
installError = True print "Error: This platform is already installed: ", fpdfile
installError = True
# Now we need to check that all the Platforms (and modules?) that are
# referenced by this fpd are installed in the workspace or are in this far.
packagesNeeded = set()
# Go through the dependencies
for dependency in XmlList(fpd, "/PlatformSurfaceArea/FrameworkModules/ModuleSA") + \
XmlList(fpd, "/PlatformSurfaceArea/FrameworkModules/ModuleSA/Libraries/Instance"):
packagesNeeded.add((string.lower(dependency.getAttribute("PackageGuid")),
dependency.getAttribute("PackageVersion")))
# Let's see if all the packages are in the workspace
for guid, version in packagesNeeded:
# Does anyone provide this package?
if not fdb.HasPackage((guid, version)) and not (guid, version) in farSpds:
print ("Error: The fpd %s depends on the package guid %s version %s, which " + \
"is not installed in the workspace, nor is it provided by this far.") \
% (fpdfile, guid, version)
installError = True
# Check the fars # Check the fars
thisFarGuid = XmlElement(manifest, "/FrameworkArchiveManifest/FarHeader/GuidValue") thisFarGuid = string.lower(XmlElement(manifest, "/FrameworkArchiveManifest/FarHeader/GuidValue"))
if fdb.HasFar(thisFarGuid): if fdb.HasFar(thisFarGuid):
print "Error: There is a far with this guid already installed." if not flags.reinstall:
installError = True print "Error: There is a far with this guid already installed."
installError = True
# We can not do the install # We can not do the install
if installError: if installError:
if force: if flags.force:
print "Ignoring previous errors as you requested." print "Warning: Ignoring previous errors as you requested."
else: else:
return False return False
@ -206,36 +245,41 @@ def InstallFar(farfile, workspaceLocation=""):
for farPackage in XmlList(manifest, "/FrameworkArchiveManifest/FarPackageList/FarPackage"): for farPackage in XmlList(manifest, "/FrameworkArchiveManifest/FarPackageList/FarPackage"):
filename = XmlElement(farPackage, "FarPackage/FarFilename") filename = XmlElement(farPackage, "FarPackage/FarFilename")
fdb.AddPackage(filename) if not flags.reinstall:
fdb.AddPackage(filename)
ExtractFile(far, filename, workspaceLocation) ExtractFile(far, filename, workspaceLocation)
zipContents.remove(filename) zipContents.remove(filename)
DefaultPath = XmlElement(farPackage, "FarPackage/DefaultPath")
for content in XmlList(farPackage, "FarPackage/Contents/FarFilename"): for content in XmlList(farPackage, "FarPackage/Contents/FarFilename"):
filename = XmlElementData(content) filename = XmlElementData(content)
ExtractFile(far, filename, workspaceLocation) ExtractFile(far, filename, DefaultPath, workspaceLocation, md5sum=content.getAttribute("Md5Sum"))
zipContents.remove(filename) zipContents.remove(os.path.join(DefaultPath, filename))
# Install the platforms # Install the platforms
for farPlatform in XmlList(manifest, "/FrameworkArchiveManifest/FarPlatformList/FarPlatform"): for farPlatform in XmlList(manifest, "/FrameworkArchiveManifest/FarPlatformList/FarPlatform"):
filename = XmlElement(farPlatform, "FarPlatform/FarFilename") filename = XmlElement(farPlatform, "FarPlatform/FarFilename")
fdb.AddPlatform(filename) if not flags.reinstall:
ExtractFile(far, filename, workspaceLocation) fdb.AddPlatform(filename)
ExtractFile(far, filename, "", workspaceLocation)
zipContents.remove(filename) zipContents.remove(filename)
# Install the Contents # Install the Contents
for content in XmlList(manifest, "/FrameworkArchiveManifest/Contents/FarFilename"): for content in XmlList(manifest, "/FrameworkArchiveManifest/Contents/FarFilename"):
filename = XmlElementData(content) filename = XmlElementData(content)
ExtractFile(far, filename, workspaceLocation) ExtractFile(far, filename, "", workspaceLocation)
zipContents.remove(filename) zipContents.remove(filename)
# What if there are more files in the far? # What if there are more files in the far?
if not zipContents == []: if not zipContents == []:
print "There are still files in the far:", zipContents print "Warning: There are files in the far that were not expected: ", zipContents
fdb.AddFar(farfile, thisFarGuid) if not flags.reinstall:
fdb.AddFar(farfile, thisFarGuid)
# If everything has gone well, we can put the manifest file in a safe place... # If everything has gone well, we can put the manifest file in a safe place...
farDir = inWorkspace("Tools/Conf/InstalledFars/") farDir = inWorkspace("Tools/Conf/InstalledFars/")
@ -245,7 +289,8 @@ def InstallFar(farfile, workspaceLocation=""):
f.close() f.close()
# Write out the new database # Write out the new database
fdb.Write() if not flags.reinstall:
fdb.Write()
far.close() far.close()
@ -253,22 +298,26 @@ def InstallFar(farfile, workspaceLocation=""):
# into another script. # into another script.
if __name__ == '__main__': if __name__ == '__main__':
flags = Flags()
# Process the command line args. # Process the command line args.
optlist, args = getopt.getopt(sys.argv[1:], '?hvf', ['help', 'verbose', 'force']) optlist, args = getopt.getopt(sys.argv[1:], '?hvf', ['help', 'verbose', 'force', 'reinstall'])
# First pass through the options list. # First pass through the options list.
for o, a in optlist: for o, a in optlist:
if o in ["-h", "--help"]: if o in ["-h", "-?", "--help"]:
print """ print """
Install a far (Framework Archive) into the current workspace. %s: Install a far (Framework Archive) into the current workspace.
""" % os.path.basename(sys.argv[0]) """ % os.path.basename(sys.argv[0])
sys.exit() sys.exit()
optlist.remove((o,a)) optlist.remove((o,a))
if o in ["-v", "--verbose"]: if o in ["-v", "--verbose"]:
verbose = True flags.verbose = True
if o in ["-f", "--force"]: if o in ["-f", "--force"]:
force = True flags.force = True
if o in ["--reinstall"]:
flags.reinstall = True
for f in args: for f in args:
InstallFar(f) InstallFar(f)

View File

@ -87,32 +87,17 @@ def makeFarHeader(doc):
"""Create a dom tree for the Far Header. It will use information from the """Create a dom tree for the Far Header. It will use information from the
template file passed on the command line, if present.""" template file passed on the command line, if present."""
header = XmlAppendChildElement(doc.documentElement, "FarHeader")
header = doc.createElement("FarHeader") XmlAppendChildElement(header, "FarName", far.FarName)
name = doc.createElement("FarName") XmlAppendChildElement(header, "GuidValue", genguid())
name.appendChild(doc.createTextNode(far.FarName)) XmlAppendChildElement(header, "Version", far.Version)
header.appendChild(name) XmlAppendChildElement(header, "Abstract", far.Abstract)
guidVal = doc.createElement("GuidValue") XmlAppendChildElement(header, "Description", far.Description)
guidVal.appendChild(doc.createTextNode(genguid())) XmlAppendChildElement(header, "Copyright", far.Copyright)
header.appendChild(guidVal) XmlAppendChildElement(header, "License", far.License)
ver = doc.createElement("Version") XmlAppendChildElement(header, "Specification", "FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052")
ver.appendChild(doc.createTextNode(far.Version))
header.appendChild(ver)
abstract = doc.createElement("Abstract")
abstract.appendChild(doc.createTextNode(far.Abstract))
header.appendChild(abstract)
desc = doc.createElement("Description")
desc.appendChild(doc.createTextNode(far.Description))
header.appendChild(desc)
copy = doc.createElement("Copyright")
copy.appendChild(doc.createTextNode(far.Copyright))
header.appendChild(copy)
lic = doc.createElement("License")
lic.appendChild(doc.createTextNode(far.License))
header.appendChild(lic)
spec = doc.createElement("Specification")
spec.appendChild(doc.createTextNode("FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052"))
header.appendChild(spec)
return header return header
@ -135,17 +120,10 @@ def makeFar(files, farname):
top_element.appendChild(makeFarHeader(man)) top_element.appendChild(makeFarHeader(man))
packList = man.createElement("FarPackageList") packList = XmlAppendChildElement(top_element, "FarPackageList")
top_element.appendChild(packList) platList = XmlAppendChildElement(top_element, "FarPlatformList")
contents = XmlAppendChildElement(top_element, "Contents")
platList = man.createElement("FarPlatformList") XmlAppendChildElement(top_element, "UserExtensions")
top_element.appendChild(platList)
contents = man.createElement("Contents")
top_element.appendChild(contents)
exts = man.createElement("UserExtensions")
top_element.appendChild(exts)
zip = zipfile.ZipFile(farname, "w") zip = zipfile.ZipFile(farname, "w")
for infile in set(files): for infile in set(files):
@ -159,77 +137,34 @@ def makeFar(files, farname):
(spdGuid, spdVersion) = getSpdGuidVersion(infile) (spdGuid, spdVersion) = getSpdGuidVersion(infile)
package = man.createElement("FarPackage") package = XmlAppendChildElement(packList, "FarPackage")
packList.appendChild(package) XmlAppendChildElement(package, "FarFilename", lean(infile), {"Md5Sum": Md5(inWorkspace(infile))})
spdfilename = farFileNode(man, inWorkspace(infile))
zip.write(inWorkspace(infile), infile) zip.write(inWorkspace(infile), infile)
spdfilename.appendChild(man.createTextNode(lean(infile))) XmlAppendChildElement(package, "GuidValue", spdGuid)
package.appendChild(spdfilename) XmlAppendChildElement(package, "Version", spdVersion)
XmlAppendChildElement(package, "DefaultPath", spdDir)
guidValue = man.createElement("GuidValue") XmlAppendChildElement(package, "FarPlatformList")
guidValue.appendChild(man.createTextNode(spdGuid)) packContents = XmlAppendChildElement(package, "Contents")
package.appendChild(guidValue) XmlAppendChildElement(package, "UserExtensions")
version = man.createElement("Version")
version.appendChild(man.createTextNode(spdVersion))
package.appendChild(version)
defaultPath = man.createElement("DefaultPath")
defaultPath.appendChild(man.createTextNode(spdDir))
package.appendChild(defaultPath)
farPlatformList = man.createElement("FarPlatformList")
package.appendChild(farPlatformList)
packContents = man.createElement("Contents")
package.appendChild(packContents)
ue = man.createElement("UserExtensions")
package.appendChild(ue)
for spdfile in filelist: for spdfile in filelist:
content = farFileNode(man, inWorkspace(os.path.join(spdDir, spdfile))) XmlAppendChildElement(packContents, "FarFilename", lean(spdfile), {"Md5Sum": Md5(inWorkspace(os.path.join(spdDir, spdfile)))})
zip.write(inWorkspace(os.path.join(spdDir, spdfile)), os.path.join(spdDir,spdfile)) zip.write(inWorkspace(os.path.join(spdDir, spdfile)), os.path.join(spdDir,spdfile))
content.appendChild(man.createTextNode(lean(spdfile)))
packContents.appendChild(content)
elif extension == ".fpd": elif extension == ".fpd":
platform = man.createElement("FarPlatform") platform = XmlAppendChildElement(platList, "FarPlatform")
platList.appendChild(platform) XmlAppendChildElement(platform, "FarFilename", lean(infile), {"Md5Sum": Md5(inWorkspace(infile))})
fpdfilename = farFileNode(man, inWorkspace(infile))
zip.write(inWorkspace(infile), infile) zip.write(inWorkspace(infile), infile)
platform.appendChild(fpdfilename)
fpdfilename.appendChild(man.createTextNode(lean(infile)))
else: else:
content = farFileNode(man, inWorkspace(infile)) XmlAppendChildElement(contents, "FarFilename", lean(infile), {"Md5Sum": Md5(inWorkspace(infile))})
zip.write(inWorkspace(infile), infile) zip.write(inWorkspace(infile), infile)
content.appendChild(man.createTextNode(lean(infile)))
contents.appendChild(content)
zip.writestr("FrameworkArchiveManifest.xml", man.toprettyxml(2*" ")) zip.writestr("FrameworkArchiveManifest.xml", man.toxml('UTF-8'))
zip.close() zip.close()
return return
def farFileNode(doc, filename):
"""This is a function that returns a dom tree for a given file that is
included in the far. An md5sum is calculated for that file."""
content = doc.createElement("FarFilename")
try:
f=open(filename, "rb")
content.setAttribute("Md5sum", md5.md5(f.read()).hexdigest())
f.close()
except IOError:
print "Error: Unable to open file: %s" % filename
sys.exit()
return content
# This acts like the main() function for the script, unless it is 'import'ed # This acts like the main() function for the script, unless it is 'import'ed
# into another script. # into another script.
if __name__ == '__main__': if __name__ == '__main__':
@ -238,7 +173,7 @@ if __name__ == '__main__':
# pp = pprint.PrettyPrinter(indent=2) # pp = pprint.PrettyPrinter(indent=2)
# Process the command line args. # Process the command line args.
optlist, args = getopt.getopt(sys.argv[1:], 'hf:t:', [ 'template=', 'far=', 'help']) optlist, args = getopt.getopt(sys.argv[1:], 'ho:t:v', [ 'template=', 'output=', 'far=', 'help', 'debug', 'verbose', 'version'])
# First pass through the options list. # First pass through the options list.
for o, a in optlist: for o, a in optlist:
@ -268,7 +203,7 @@ is a text file that allows more contol over the contents of the far.
# Second pass through the options list. These can override the first pass. # Second pass through the options list. These can override the first pass.
for o, a in optlist: for o, a in optlist:
print o, a print o, a
if o in ["-f", "--far"]: if o in ["-o", "--far", "--output"]:
far.FileName = a far.FileName = a
# Let's err on the side of caution and not let people blow away data # Let's err on the side of caution and not let people blow away data

View File

@ -42,3 +42,19 @@ def mkdir(path):
except: except:
pass pass
def Md5(filename):
sum = ""
try:
f=open(filename, "rb")
sum = md5.md5(f.read()).hexdigest()
f.close()
except IOError:
print "Error: Unable to open file: %s" % filename
sys.exit()
return sum