]>
git.proxmox.com Git - mirror_edk2.git/blob - Tools/Python/InstallFar.py
3 """This is a python script that takes user input from the command line and
4 installs a far (Framework Archive Manifest) file into the workspace."""
6 import os
, sys
, getopt
, string
, xml
.dom
.minidom
, zipfile
, md5
7 from XmlRoutines
import *
8 from WorkspaceRoutines
import *
15 def __init__(self
, filename
="Tools/Conf/FrameworkDatabase.db"):
17 # First try to get a lock file.
18 self
.DBFile
= inWorkspace(filename
)
19 self
.lockfile
= inWorkspace("Tools/Conf/FrameworkDatabase.lock")
20 if os
.path
.exists(self
.lockfile
):
21 self
.itsMyLockFile
= False
22 print "Error: The database file is locked by ", self
.lockfile
23 raise OSError("The Database is locked.")
25 self
.lock
= open(self
.lockfile
, 'w')
26 self
.lock
.write("pid "+str(os
.getpid()))
27 self
.itsMyLockFile
= True
29 self
.dom
= XmlParseFile(inWorkspace(filename
))
31 self
.installedPackages
= {}
32 self
.installedPlatforms
= {}
33 self
.installedFars
= {}
35 for spdfile
in XmlList(self
.dom
, "/FrameworkDatabase/PackageList/Filename"):
36 filename
= str(XmlElementData(spdfile
))
37 spd
= XmlParseFileSection(inWorkspace(filename
), "SpdHeader")
38 self
.installedPackages
[XmlElement(spd
, "/SpdHeader/GuidValue"), XmlElement(spd
, "/SpdHeader/Version")] = \
39 XmlElement(spd
, "/SpdHeader/PackageName")
41 for fpdfile
in XmlList(self
.dom
, "/FrameworkDatabase/PlatformList/Filename"):
42 filename
= str(XmlElementData(fpdfile
))
43 fpd
= XmlParseFileSection(inWorkspace(filename
), "PlatformHeader")
44 self
.installedPlatforms
[XmlElement(fpd
, "/PlatformHeader/GuidValue"), XmlElement(fpd
, "/PlatformHeader/Version") ] = \
45 XmlElement(fpd
, "/PlatformHeader/PlatformName")
47 for farfile
in XmlList(self
.dom
, "/FrameworkDatabase/FarList/Filename"):
48 farGuid
= farfile
.getAttribute("FarGuid")
49 self
.installedFars
[farGuid
] = XmlElementData(farfile
)
51 self
.packageList
= XmlNode(self
.dom
, "/FrameworkDatabase/PackageList")
52 self
.platformList
= XmlNode(self
.dom
, "/FrameworkDatabase/PlatformList")
53 self
.farList
= XmlNode(self
.dom
, "/FrameworkDatabase/FarList")
56 if self
.itsMyLockFile
:
58 os
.unlink(self
.lockfile
)
60 def HasPackage(self
, (guid
, version
)):
61 """Return true iff this package is already installed."""
64 for (g
, v
) in self
.installedPackages
.keys():
67 return self
.installedPackages
.has_key((guid
, version
))
69 def HasPlatform(self
, (guid
, version
)):
70 """Return true iff this platform is already installed."""
73 for (g
, v
) in self
.installedPlatforms
.keys():
76 return self
.installedPlatforms
.has_key((guid
, version
))
78 def HasFar(self
, farguid
):
79 """Return true iff this far is already installed."""
80 return self
.installedFars
.has_key(farguid
)
82 def AddPackage(self
, f
):
83 filename
= self
.dom
.createElement("Filename")
84 filename
.appendChild(self
.dom
.createTextNode(f
))
85 self
.packageList
.appendChild(filename
)
87 def AddPlatform(self
, f
):
88 filename
= self
.dom
.createElement("Filename")
89 filename
.appendChild(self
.dom
.createTextNode(f
))
90 self
.platformList
.appendChild(filename
)
92 def AddFar(self
, f
, guid
=""):
93 filename
= self
.dom
.createElement("Filename")
94 filename
.setAttribute("FarGuid", guid
)
95 filename
.appendChild(self
.dom
.createTextNode(f
))
96 self
.farList
.appendChild(filename
)
100 XmlSaveFile(self
.dom
, self
.DBFile
)
102 f
=open(self
.DBFile
, 'w')
103 f
.write(self
.dom
.toprettyxml(2*" "))
106 def ExtractFile(zip, file, workspaceLocation
=""):
109 print "Extracting ", file
111 destFile
= os
.path
.join(inWorkspace(workspaceLocation
), str(file))
112 destDir
= os
.path
.dirname(destFile
)
116 f
= open(destFile
, "w")
117 f
.write(zip.read(file))
120 def GetFpdGuidVersion(Dom
):
122 """Get the Guid and version of the fpd from a dom object."""
124 return XmlElement(Dom
, "/PlatformSurfaceArea/PlatformHeader/GuidValue"), \
125 XmlElement(Dom
, "/PlatformSurfaceArea/PlatformHeader/Version")
127 def GetSpdGuidVersion(Dom
):
129 """Get the Guid and version of the spd from a dom object."""
131 return XmlElement(Dom
, "/PackageSurfaceArea/SpdHeader/GuidValue"), \
132 XmlElement(Dom
, "/PackageSurfaceArea/SpdHeader/Version")
134 def InstallFar(farfile
, workspaceLocation
=""):
136 far
= zipfile
.ZipFile(farfile
, "r")
138 # Use this list to make sure we get everything from the far.
139 zipContents
= far
.namelist()
141 manifest
= xml
.dom
.minidom
.parseString(far
.read("FrameworkArchiveManifest.xml"))
142 zipContents
.remove("FrameworkArchiveManifest.xml")
145 # First we need to make sure that the far will install cleanly.
147 installError
= False # Let's hope for the best.
152 for farPackage
in XmlList(manifest
, "/FrameworkArchiveManifest/FarPackageList/FarPackage/FarFilename"):
153 spdfile
= str(XmlElementData(farPackage
))
154 spd
= XmlParseString(far
.read(spdfile
))
155 packageGV
= GetSpdGuidVersion(spd
)
156 if fdb
.HasPackage(packageGV
):
157 print "Error: This package is already installed: ", spdfile
160 # Build up a list of the package guid versions that this far is bringing in.
161 # This is needed to satisfy dependencies of msas that are in the other packages of
164 farSpds
.append(packageGV
)
169 # Now we need to get a list of every msa in this spd and check the package dependencies.
170 for msafile
in XmlList(spd
, "/PackageSurfaceArea/MsaFiles/Filename"):
171 msafilePath
= str(os
.path
.join(os
.path
.dirname(spdfile
), XmlElementData(msafile
)))
173 msa
= XmlParseString(far
.read(msafilePath
))
175 for package
in XmlList(msa
, "/ModuleSurfaceArea/PackageDependencies/Package"):
176 guid
= package
.getAttribute("PackageGuid")
177 version
= package
.getAttribute("PackageVersion")
179 if not fdb
.HasPackage((guid
, version
)) and not (guid
, version
) in farSpds
:
180 print "The module %s depends on the package guid % version %s, which is not installed in the workspace." \
181 % (msafilePath
, guid
, version
)
184 # Check the platforms
185 for farPlatform
in XmlList(manifest
, "/FrameworkArchiveManifest/FarPlatformList/FarPlatform/FarFilename"):
186 fpdfile
= str(XmlElementData(farPlatform
))
187 fpd
= XmlParseString(far
.read(fpdfile
))
188 if fdb
.HasPlatform(GetFpdGuidVersion(fpd
)):
189 print "Error: This platform is already installed: ", fpdfile
193 thisFarGuid
= XmlElement(manifest
, "/FrameworkArchiveManifest/FarHeader/GuidValue")
194 if fdb
.HasFar(thisFarGuid
):
195 print "Error: There is a far with this guid already installed."
198 # We can not do the install
201 print "Ignoring previous errors as you requested."
205 # Install the packages
206 for farPackage
in XmlList(manifest
, "/FrameworkArchiveManifest/FarPackageList/FarPackage"):
208 filename
= XmlElement(farPackage
, "FarPackage/FarFilename")
209 fdb
.AddPackage(filename
)
210 ExtractFile(far
, filename
, workspaceLocation
)
211 zipContents
.remove(filename
)
213 for content
in XmlList(farPackage
, "FarPackage/Contents/FarFilename"):
215 filename
= XmlElementData(content
)
216 ExtractFile(far
, filename
, workspaceLocation
)
217 zipContents
.remove(filename
)
219 # Install the platforms
220 for farPlatform
in XmlList(manifest
, "/FrameworkArchiveManifest/FarPlatformList/FarPlatform"):
222 filename
= XmlElement(farPlatform
, "FarPlatform/FarFilename")
223 fdb
.AddPlatform(filename
)
224 ExtractFile(far
, filename
, workspaceLocation
)
225 zipContents
.remove(filename
)
227 # Install the Contents
228 for content
in XmlList(manifest
, "/FrameworkArchiveManifest/Contents/FarFilename"):
230 filename
= XmlElementData(content
)
231 ExtractFile(far
, filename
, workspaceLocation
)
232 zipContents
.remove(filename
)
234 # What if there are more files in the far?
235 if not zipContents
== []:
236 print "There are still files in the far:", zipContents
238 fdb
.AddFar(farfile
, thisFarGuid
)
240 # If everything has gone well, we can put the manifest file in a safe place...
241 farDir
= inWorkspace("Tools/Conf/InstalledFars/")
243 f
=open(os
.path
.join(farDir
, thisFarGuid
), 'w')
244 f
.write(far
.read("FrameworkArchiveManifest.xml"))
247 # Write out the new database
252 # This acts like the main() function for the script, unless it is 'import'ed
253 # into another script.
254 if __name__
== '__main__':
256 # Process the command line args.
257 optlist
, args
= getopt
.getopt(sys
.argv
[1:], '?hvf', ['help', 'verbose', 'force'])
259 # First pass through the options list.
261 if o
in ["-h", "--help"]:
263 Install a far (Framework Archive) into the current workspace.
264 """ % os
.path
.basename(sys
.argv
[0])
267 optlist
.remove((o
,a
))
268 if o
in ["-v", "--verbose"]:
270 if o
in ["-f", "--force"]:
276 print "Please pass a far filename on the command line."