]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/UPT/InstallPkg.py
Sync BaseTool trunk (version r2474) into EDKII BaseTools.
[mirror_edk2.git] / BaseTools / Source / Python / UPT / InstallPkg.py
CommitLineData
4234283c
LG
1## @file\r
2# Install distribution package.\r
3#\r
4# Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>\r
5#\r
6# This program and the accompanying materials are licensed and made available \r
7# under the terms and conditions of the BSD License which accompanies this \r
8# distribution. The full text of the license may be found at \r
9# http://opensource.org/licenses/bsd-license.php\r
10#\r
11# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
12# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
13#\r
14"""\r
15Install a distribution package\r
16"""\r
17##\r
18# Import Modules\r
19#\r
20import os.path\r
21from os import chmod\r
22from os import SEEK_SET\r
23from os import SEEK_END\r
24import stat\r
25import md5\r
26from sys import stdin\r
27from sys import platform\r
28from shutil import rmtree\r
29from shutil import copyfile\r
30from traceback import format_exc\r
31from platform import python_version\r
32\r
33from Logger import StringTable as ST\r
34from Logger.ToolError import UNKNOWN_ERROR\r
35from Logger.ToolError import FILE_UNKNOWN_ERROR\r
36from Logger.ToolError import OPTION_MISSING\r
37from Logger.ToolError import UPT_ALREADY_INSTALLED_ERROR\r
38from Logger.ToolError import FatalError\r
39from Logger.ToolError import ABORT_ERROR\r
40from Logger.ToolError import CODE_ERROR\r
41from Logger.ToolError import FORMAT_INVALID\r
42from Logger.ToolError import FILE_TYPE_MISMATCH\r
43import Logger.Log as Logger\r
44\r
45from Library.Misc import CheckEnvVariable\r
46from Library.Misc import Sdict\r
47from Library.Misc import ConvertPath\r
48from Library.ParserValidate import IsValidInstallPath\r
49from Xml.XmlParser import DistributionPackageXml\r
50from GenMetaFile.GenDecFile import PackageToDec\r
51from GenMetaFile.GenInfFile import ModuleToInf\r
52from Core.PackageFile import PackageFile\r
53from Core.PackageFile import FILE_NOT_FOUND\r
54from Core.PackageFile import FILE_CHECKSUM_FAILURE\r
55from Core.PackageFile import CreateDirectory\r
56from Core.DependencyRules import DependencyRules\r
57from Library import GlobalData\r
58\r
59## InstallNewPackage\r
60#\r
61# @param WorkspaceDir: Workspace Directory\r
62# @param Path: Package Path\r
63# @param CustomPath: whether need to customize path at first\r
64#\r
65def InstallNewPackage(WorkspaceDir, Path, CustomPath = False):\r
66 if os.path.isabs(Path):\r
67 Logger.Info(ST.MSG_RELATIVE_PATH_ONLY%Path)\r
68 elif CustomPath:\r
69 Logger.Info(ST.MSG_NEW_PKG_PATH)\r
70 else:\r
71 Path = ConvertPath(Path)\r
72 Path = os.path.normpath(Path)\r
73 FullPath = os.path.normpath(os.path.join(WorkspaceDir, Path))\r
74 if os.path.exists(FullPath):\r
75 Logger.Info(ST.ERR_DIR_ALREADY_EXIST%FullPath)\r
76 else:\r
77 return Path\r
78\r
79 Input = stdin.readline()\r
80 Input = Input.replace('\r', '').replace('\n', '')\r
81 if Input == '':\r
82 Logger.Error("InstallPkg", UNKNOWN_ERROR, ST.ERR_USER_INTERRUPT)\r
83 Input = Input.replace('\r', '').replace('\n', '')\r
84 return InstallNewPackage(WorkspaceDir, Input, False)\r
85\r
86\r
87## InstallNewModule\r
88#\r
89# @param WorkspaceDir: Workspace Directory\r
90# @param Path: Standalone Module Path\r
91# @param PathList: The already installed standalone module Path list\r
92#\r
93def InstallNewModule(WorkspaceDir, Path, PathList = None):\r
94 if PathList == None:\r
95 PathList = []\r
96 Path = ConvertPath(Path)\r
97 Path = os.path.normpath(Path)\r
98 FullPath = os.path.normpath(os.path.join(WorkspaceDir, Path))\r
99 if os.path.exists(FullPath) and FullPath not in PathList:\r
100 Logger.Info(ST.ERR_DIR_ALREADY_EXIST%Path)\r
101 elif Path == FullPath:\r
102 Logger.Info(ST.MSG_RELATIVE_PATH_ONLY%FullPath)\r
103 else:\r
104 return Path\r
105 \r
106 Input = stdin.readline()\r
107 Input = Input.replace('\r', '').replace('\n', '')\r
108 if Input == '':\r
109 Logger.Error("InstallPkg", UNKNOWN_ERROR, ST.ERR_USER_INTERRUPT)\r
110 Input = Input.replace('\r', '').replace('\n', '')\r
111 return InstallNewModule(WorkspaceDir, Input, PathList)\r
112\r
113 \r
114## InstallNewFile\r
115#\r
116# @param WorkspaceDir: Workspace Direction\r
117# @param File: File\r
118#\r
119def InstallNewFile(WorkspaceDir, File):\r
120 FullPath = os.path.normpath(os.path.join(WorkspaceDir, File))\r
121 if os.path.exists(FullPath):\r
122 Logger.Info(ST.ERR_FILE_ALREADY_EXIST %File)\r
123 Input = stdin.readline()\r
124 Input = Input.replace('\r', '').replace('\n', '')\r
125 if Input == '':\r
126 Logger.Error("InstallPkg", UNKNOWN_ERROR, ST.ERR_USER_INTERRUPT)\r
127 Input = Input.replace('\r', '').replace('\n', '')\r
128 return InstallNewFile(WorkspaceDir, Input)\r
129 else:\r
130 return File\r
131\r
132## UnZipDp\r
133#\r
134# UnZipDp\r
135#\r
136def UnZipDp(WorkspaceDir, Options, DataBase):\r
137 ContentZipFile = None\r
138 Logger.Quiet(ST.MSG_UZIP_PARSE_XML)\r
139 DpPkgFileName = Options.PackageFile\r
140 DistFile = PackageFile(DpPkgFileName)\r
141 \r
142 DpDescFileName, ContentFileName = GetDPFile(DistFile.GetZipFile())\r
143 \r
144 GlobalData.gUNPACK_DIR = os.path.normpath(os.path.join(WorkspaceDir, ".tmp"))\r
145 DistPkgFile = DistFile.UnpackFile(DpDescFileName,\r
146 os.path.normpath(os.path.join(GlobalData.gUNPACK_DIR, DpDescFileName)))\r
147 if not DistPkgFile:\r
148 Logger.Error("InstallPkg", FILE_NOT_FOUND, ST.ERR_FILE_BROKEN %DpDescFileName)\r
149 \r
150 #\r
151 # Generate distpkg\r
152 #\r
153 DistPkgObj = DistributionPackageXml()\r
154 DistPkg = DistPkgObj.FromXml(DistPkgFile)\r
155 if DistPkg.Header.RePackage == '':\r
156 DistPkg.Header.RePackage = False\r
157 if DistPkg.Header.ReadOnly == '':\r
158 DistPkg.Header.ReadOnly = False\r
159 \r
160 #\r
161 # prepare check dependency\r
162 #\r
163 Dep = DependencyRules(DataBase)\r
164 #\r
165 # Check distribution package installed or not\r
166 #\r
167 if Dep.CheckDpExists(DistPkg.Header.GetGuid(),\r
168 DistPkg.Header.GetVersion()):\r
169 Logger.Error("InstallPkg", UPT_ALREADY_INSTALLED_ERROR,\r
170 ST.WRN_DIST_PKG_INSTALLED)\r
171 #\r
172 # Check distribution dependency (all module dependency should be\r
173 # satisfied)\r
174 #\r
175 if not Dep.CheckDpDepexSatisfied(DistPkg):\r
176 Logger.Error("InstallPkg", UNKNOWN_ERROR,\r
177 ST.ERR_PACKAGE_NOT_MATCH_DEPENDENCY,\r
178 ExtraData=DistPkg.Header.Name)\r
179 #\r
180 # unzip contents.zip file\r
181 #\r
182 ContentFile = DistFile.UnpackFile(ContentFileName,\r
183 os.path.normpath(os.path.join(GlobalData.gUNPACK_DIR, ContentFileName)))\r
184 if not ContentFile:\r
185 Logger.Error("InstallPkg", FILE_NOT_FOUND,\r
186 ST.ERR_FILE_BROKEN % ContentFileName)\r
187\r
188 FilePointer = open(ContentFile, "rb")\r
189 #\r
190 # Assume no archive comment.\r
191 #\r
192 FilePointer.seek(0, SEEK_SET)\r
193 FilePointer.seek(0, SEEK_END)\r
194 #\r
195 # Get file size\r
196 # \r
197 FileSize = FilePointer.tell()\r
198 FilePointer.close()\r
199 \r
200 if FileSize != 0: \r
201 ContentZipFile = PackageFile(ContentFile)\r
202\r
203 #\r
204 # verify MD5 signature when existed\r
205 #\r
206 if DistPkg.Header.Signature != '':\r
207 Md5Sigature = md5.new(open(ContentFile, 'rb').read())\r
208 if DistPkg.Header.Signature != Md5Sigature.hexdigest():\r
209 ContentZipFile.Close()\r
210 Logger.Error("InstallPkg", FILE_CHECKSUM_FAILURE,\r
211 ExtraData=ContentFile)\r
212\r
213 return DistPkg, Dep, ContentZipFile, DpPkgFileName\r
214\r
215## GetPackageList\r
216#\r
217# GetPackageList\r
218#\r
219def GetPackageList(DistPkg, Dep, WorkspaceDir, Options, ContentZipFile, ModuleList, PackageList):\r
220 NewDict = Sdict()\r
221 for Guid, Version, Path in DistPkg.PackageSurfaceArea:\r
222 PackagePath = Path\r
223 Package = DistPkg.PackageSurfaceArea[Guid, Version, Path]\r
224 Logger.Info(ST.MSG_INSTALL_PACKAGE % Package.GetName())\r
225 if Dep.CheckPackageExists(Guid, Version):\r
226 Logger.Info(ST.WRN_PACKAGE_EXISTED %(Guid, Version))\r
227 NewPackagePath = InstallNewPackage(WorkspaceDir, PackagePath, Options.CustomPath)\r
228 InstallPackageContent(PackagePath, NewPackagePath, Package, ContentZipFile, Dep, WorkspaceDir, ModuleList, \r
229 DistPkg.Header.ReadOnly)\r
230 PackageList.append(Package)\r
231 \r
232 NewDict[Guid, Version, Package.GetPackagePath()] = Package\r
233 \r
234 #\r
235 # Now generate meta-data files, first generate all dec for package\r
236 # dec should be generated before inf, and inf should be generated after\r
237 # all packages installed, else hard to resolve modules' package\r
238 # dependency (Hard to get the location of the newly installed package)\r
239 #\r
240 for Package in PackageList:\r
241 FilePath = PackageToDec(Package)\r
242 Md5Sigature = md5.new(open(str(FilePath), 'rb').read())\r
243 Md5Sum = Md5Sigature.hexdigest()\r
244 if (FilePath, Md5Sum) not in Package.FileList:\r
245 Package.FileList.append((FilePath, Md5Sum))\r
246 \r
247 return NewDict\r
248\r
249## GetModuleList\r
250#\r
251# GetModuleList\r
252#\r
253def GetModuleList(DistPkg, Dep, WorkspaceDir, ContentZipFile, ModuleList):\r
254 #\r
255 # ModulePathList will keep track of the standalone module path that\r
256 # we just installed. If a new module's path in that list \r
257 # (only multiple INF in one directory will be so), we will \r
258 # install them directly. If not, we will try to create a new directory \r
259 # for it.\r
260 #\r
261 ModulePathList = [] \r
262 \r
263 #\r
264 # Check module exist and install\r
265 #\r
266 Module = None\r
267 NewDict = Sdict() \r
d0acc87a 268 for Guid, Version, Name, Path in DistPkg.ModuleSurfaceArea:\r
4234283c 269 ModulePath = Path\r
d0acc87a 270 Module = DistPkg.ModuleSurfaceArea[Guid, Version, Name, Path]\r
4234283c 271 Logger.Info(ST.MSG_INSTALL_MODULE % Module.GetName())\r
d0acc87a 272 if Dep.CheckModuleExists(Guid, Version, Name, Path):\r
4234283c
LG
273 Logger.Quiet(ST.WRN_MODULE_EXISTED %Path)\r
274 #\r
275 # here check for the multiple inf share the same module path cases:\r
276 # they should be installed into the same directory\r
277 #\r
278 ModuleFullPath = \\r
279 os.path.normpath(os.path.join(WorkspaceDir, ModulePath))\r
280 if ModuleFullPath not in ModulePathList:\r
281 NewModulePath = InstallNewModule(WorkspaceDir, ModulePath, ModulePathList)\r
282 NewModuleFullPath = os.path.normpath(os.path.join(WorkspaceDir, NewModulePath))\r
283 ModulePathList.append(NewModuleFullPath)\r
284 else:\r
285 NewModulePath = ModulePath\r
286 \r
287 InstallModuleContent(ModulePath, NewModulePath, '', Module, ContentZipFile, WorkspaceDir, ModuleList, None, \r
288 DistPkg.Header.ReadOnly)\r
289 #\r
290 # Update module\r
291 #\r
292 Module.SetModulePath(Module.GetModulePath().replace(Path, NewModulePath, 1))\r
293 \r
d0acc87a 294 NewDict[Guid, Version, Name, Module.GetModulePath()] = Module\r
4234283c
LG
295\r
296 #\r
297 # generate all inf for modules\r
298 #\r
299 for (Module, Package) in ModuleList:\r
300 FilePath = ModuleToInf(Module)\r
301 Md5Sigature = md5.new(open(str(FilePath), 'rb').read())\r
302 Md5Sum = Md5Sigature.hexdigest()\r
303 if Package:\r
304 if (FilePath, Md5Sum) not in Package.FileList:\r
305 Package.FileList.append((FilePath, Md5Sum))\r
306 else:\r
307 if (FilePath, Md5Sum) not in Module.FileList:\r
308 Module.FileList.append((FilePath, Md5Sum))\r
309 \r
310 return NewDict\r
311\r
312## GenToolMisc\r
313#\r
314# GenToolMisc\r
315#\r
316#\r
317def GenToolMisc(DistPkg, WorkspaceDir, ContentZipFile):\r
318 ToolObject = DistPkg.Tools\r
319 MiscObject = DistPkg.MiscellaneousFiles\r
320 DistPkg.FileList = []\r
321 FileList = []\r
322 ToolFileNum = 0\r
323 FileNum = 0\r
324 RootDir = WorkspaceDir\r
325 \r
326 #\r
327 # FileList stores both tools files and misc files\r
328 # Misc file list must be appended to FileList *AFTER* Tools file list\r
329 #\r
330 if ToolObject:\r
331 FileList += ToolObject.GetFileList()\r
332 ToolFileNum = len(ToolObject.GetFileList())\r
333 if 'EDK_TOOLS_PATH' in os.environ:\r
334 RootDir = os.environ['EDK_TOOLS_PATH']\r
335 if MiscObject:\r
336 FileList += MiscObject.GetFileList()\r
337 for FileObject in FileList:\r
338 FileNum += 1\r
339 if FileNum > ToolFileNum:\r
340 #\r
341 # Misc files, root should be changed to WORKSPACE\r
342 #\r
343 RootDir = WorkspaceDir\r
344 File = ConvertPath(FileObject.GetURI())\r
345 ToFile = os.path.normpath(os.path.join(RootDir, File))\r
346 if os.path.exists(ToFile):\r
347 Logger.Info( ST.WRN_FILE_EXISTED % ToFile )\r
348 #\r
349 # ask for user input the new file name\r
350 #\r
351 Logger.Info( ST.MSG_NEW_FILE_NAME)\r
352 Input = stdin.readline()\r
353 Input = Input.replace('\r', '').replace('\n', '')\r
354 OrigPath = os.path.split(ToFile)[0]\r
355 ToFile = os.path.normpath(os.path.join(OrigPath, Input))\r
356 FromFile = os.path.join(FileObject.GetURI())\r
357 Md5Sum = InstallFile(ContentZipFile, FromFile, ToFile, DistPkg.Header.ReadOnly, FileObject.GetExecutable())\r
358 DistPkg.FileList.append((ToFile, Md5Sum))\r
359\r
360## Tool entrance method\r
361#\r
362# This method mainly dispatch specific methods per the command line options.\r
363# If no error found, return zero value so the caller of this tool can know\r
364# if it's executed successfully or not.\r
365#\r
366# @param Options: command Options\r
367#\r
368def Main(Options = None):\r
369 ContentZipFile, DistFile = None, None\r
370\r
371 try:\r
372 DataBase = GlobalData.gDB \r
373 CheckEnvVariable()\r
374 WorkspaceDir = GlobalData.gWORKSPACE\r
375 if not Options.PackageFile:\r
376 Logger.Error("InstallPkg", OPTION_MISSING, ExtraData=ST.ERR_SPECIFY_PACKAGE)\r
377 \r
378 #\r
379 # unzip dist.pkg file\r
380 #\r
381 DistPkg, Dep, ContentZipFile, DpPkgFileName = UnZipDp(WorkspaceDir, Options, DataBase)\r
382\r
383 #\r
384 # PackageList, ModuleList record the information for the meta-data\r
385 # files that need to be generated later\r
386 #\r
387 PackageList = []\r
388 ModuleList = []\r
389 DistPkg.PackageSurfaceArea = GetPackageList(DistPkg, Dep, WorkspaceDir, Options, \r
390 ContentZipFile, ModuleList, PackageList)\r
391\r
392 DistPkg.ModuleSurfaceArea = GetModuleList(DistPkg, Dep, WorkspaceDir, ContentZipFile, ModuleList) \r
393 \r
394 \r
395 GenToolMisc(DistPkg, WorkspaceDir, ContentZipFile)\r
396 \r
397 #\r
398 # copy "Distribution File" to directory $(WORKSPACE)/conf/upt\r
399 #\r
400 DistFileName = os.path.split(DpPkgFileName)[1]\r
401 DestDir = os.path.normpath(os.path.join(WorkspaceDir, GlobalData.gUPT_DIR))\r
402 CreateDirectory(DestDir)\r
403 DestFile = os.path.normpath(os.path.join(DestDir, DistFileName))\r
404 if os.path.exists(DestFile):\r
405 FileName, Ext = os.path.splitext(DistFileName)\r
9508d0fa 406 NewFileName = FileName + '_' + DistPkg.Header.GetGuid() + '_' + DistPkg.Header.GetVersion() + Ext\r
4234283c
LG
407 DestFile = os.path.normpath(os.path.join(DestDir, NewFileName))\r
408 if os.path.exists(DestFile):\r
409 #\r
410 # ask for user input the new file name\r
411 #\r
412 Logger.Info( ST.MSG_NEW_FILE_NAME_FOR_DIST)\r
413 Input = stdin.readline()\r
414 Input = Input.replace('\r', '').replace('\n', '')\r
415 DestFile = os.path.normpath(os.path.join(DestDir, Input))\r
416 copyfile(DpPkgFileName, DestFile)\r
417 NewDpPkgFileName = DestFile[DestFile.find(DestDir) + len(DestDir) + 1:]\r
418\r
419 #\r
420 # update database\r
421 #\r
422 Logger.Quiet(ST.MSG_UPDATE_PACKAGE_DATABASE)\r
423 DataBase.AddDPObject(DistPkg, NewDpPkgFileName, DistFileName, \r
424 DistPkg.Header.RePackage)\r
425 \r
426 ReturnCode = 0\r
427 \r
428 except FatalError, XExcept:\r
429 ReturnCode = XExcept.args[0]\r
430 if Logger.GetLevel() <= Logger.DEBUG_9:\r
431 Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(),\r
432 platform) + format_exc())\r
433 except KeyboardInterrupt:\r
434 ReturnCode = ABORT_ERROR\r
435 if Logger.GetLevel() <= Logger.DEBUG_9:\r
436 Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(),\r
437 platform) + format_exc())\r
438 except:\r
439 ReturnCode = CODE_ERROR\r
440 Logger.Error(\r
441 "\nInstallPkg",\r
442 CODE_ERROR,\r
443 ST.ERR_UNKNOWN_FATAL_INSTALL_ERR % Options.PackageFile,\r
444 ExtraData=ST.MSG_SEARCH_FOR_HELP,\r
445 RaiseError=False\r
446 )\r
447 Logger.Quiet(ST.MSG_PYTHON_ON % (python_version(),\r
448 platform) + format_exc())\r
449\r
450 finally:\r
451 Logger.Quiet(ST.MSG_REMOVE_TEMP_FILE_STARTED)\r
452 if DistFile:\r
453 DistFile.Close()\r
454 if ContentZipFile:\r
455 ContentZipFile.Close()\r
456 if GlobalData.gUNPACK_DIR:\r
457 rmtree(GlobalData.gUNPACK_DIR)\r
458 GlobalData.gUNPACK_DIR = None\r
459 Logger.Quiet(ST.MSG_REMOVE_TEMP_FILE_DONE)\r
460\r
461 if ReturnCode == 0:\r
462 Logger.Quiet(ST.MSG_FINISH)\r
463 \r
464 return ReturnCode\r
465\r
466## InstallModuleContent method\r
467#\r
468# If this is standalone module, then Package should be none,\r
469# ModulePath should be ''\r
470# @param FromPath: FromPath\r
471# @param NewPath: NewPath\r
472# @param ModulePath: ModulePath\r
473# @param Module: Module\r
474# @param ContentZipFile: ContentZipFile\r
475# @param WorkspaceDir: WorkspaceDir\r
476# @param ModuleList: ModuleList\r
477# @param Package: Package\r
478#\r
479def InstallModuleContent(FromPath, NewPath, ModulePath, Module, ContentZipFile,\r
480 WorkspaceDir, ModuleList, Package = None, ReadOnly = False):\r
481 \r
482 if NewPath.startswith("\\") or NewPath.startswith("/"):\r
483 NewPath = NewPath[1:]\r
484 \r
485 if not IsValidInstallPath(NewPath):\r
486 Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%NewPath) \r
487 \r
488 NewModuleFullPath = os.path.normpath(os.path.join(WorkspaceDir, NewPath,\r
489 ConvertPath(ModulePath)))\r
490 Module.SetFullPath(os.path.normpath(os.path.join(NewModuleFullPath,\r
491 ConvertPath(Module.GetName()) + '.inf')))\r
492 Module.FileList = []\r
493 \r
494 for MiscFile in Module.GetMiscFileList():\r
495 if not MiscFile:\r
496 continue\r
497 for Item in MiscFile.GetFileList():\r
498 File = Item.GetURI()\r
499 if File.startswith("\\") or File.startswith("/"):\r
500 File = File[1:]\r
501 \r
502 if not IsValidInstallPath(File):\r
503 Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%File)\r
504 \r
505 FromFile = os.path.join(FromPath, ModulePath, File)\r
506 Executable = Item.GetExecutable() \r
507 ToFile = os.path.normpath(os.path.join(NewModuleFullPath, ConvertPath(File)))\r
508 Md5Sum = InstallFile(ContentZipFile, FromFile, ToFile, ReadOnly, Executable)\r
509 if Package and ((ToFile, Md5Sum) not in Package.FileList):\r
510 Package.FileList.append((ToFile, Md5Sum))\r
511 elif Package:\r
512 continue\r
513 elif (ToFile, Md5Sum) not in Module.FileList:\r
514 Module.FileList.append((ToFile, Md5Sum))\r
515 for Item in Module.GetSourceFileList():\r
516 File = Item.GetSourceFile()\r
517 if File.startswith("\\") or File.startswith("/"):\r
518 File = File[1:]\r
519 \r
520 if not IsValidInstallPath(File):\r
521 Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%File) \r
522 \r
523 FromFile = os.path.join(FromPath, ModulePath, File)\r
524 ToFile = os.path.normpath(os.path.join(NewModuleFullPath, ConvertPath(File)))\r
525 Md5Sum = InstallFile(ContentZipFile, FromFile, ToFile, ReadOnly)\r
526 if Package and ((ToFile, Md5Sum) not in Package.FileList):\r
527 Package.FileList.append((ToFile, Md5Sum))\r
528 elif Package:\r
529 continue\r
530 elif (ToFile, Md5Sum) not in Module.FileList:\r
531 Module.FileList.append((ToFile, Md5Sum))\r
532 for Item in Module.GetBinaryFileList():\r
533 FileNameList = Item.GetFileNameList()\r
534 for FileName in FileNameList: \r
535 File = FileName.GetFilename() \r
536 if File.startswith("\\") or File.startswith("/"):\r
537 File = File[1:]\r
538 \r
539 if not IsValidInstallPath(File):\r
540 Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%File)\r
541\r
542 FromFile = os.path.join(FromPath, ModulePath, File)\r
543 ToFile = os.path.normpath(os.path.join(NewModuleFullPath, ConvertPath(File)))\r
544 Md5Sum = InstallFile(ContentZipFile, FromFile, ToFile, ReadOnly) \r
545 if Package and ((ToFile, Md5Sum) not in Package.FileList):\r
546 Package.FileList.append((ToFile, Md5Sum))\r
547 elif Package:\r
548 continue\r
549 elif (ToFile, Md5Sum) not in Module.FileList:\r
550 Module.FileList.append((ToFile, Md5Sum))\r
551 \r
552 InstallModuleContentZipFile(ContentZipFile, FromPath, ModulePath, WorkspaceDir, NewPath, Module, Package, ReadOnly,\r
553 ModuleList)\r
554\r
555## InstallModuleContentZipFile\r
556#\r
557# InstallModuleContentZipFile\r
558#\r
559def InstallModuleContentZipFile(ContentZipFile, FromPath, ModulePath, WorkspaceDir, NewPath, Module, Package, ReadOnly,\r
560 ModuleList):\r
561 #\r
562 # Extract other files under current module path in content Zip file but not listed in the description \r
563 #\r
564 if ContentZipFile:\r
565 for FileName in ContentZipFile.GetZipFile().namelist():\r
566 FileName = os.path.normpath(FileName)\r
567 CheckPath = os.path.normpath(os.path.join(FromPath, ModulePath))\r
568 if FileUnderPath(FileName, CheckPath):\r
569 if FileName.startswith("\\") or FileName.startswith("/"):\r
570 FileName = FileName[1:]\r
571 \r
572 if not IsValidInstallPath(FileName):\r
573 Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%FileName)\r
574 \r
575 FromFile = FileName\r
576 ToFile = os.path.normpath(os.path.join(WorkspaceDir, \r
577 ConvertPath(FileName.replace(FromPath, NewPath, 1))))\r
578 CheckList = Module.FileList\r
579 if Package:\r
580 CheckList += Package.FileList\r
581 for Item in CheckList:\r
582 if Item[0] == ToFile:\r
583 break\r
584 else:\r
585 Md5Sum = InstallFile(ContentZipFile, FromFile, ToFile, ReadOnly)\r
586 if Package and ((ToFile, Md5Sum) not in Package.FileList):\r
587 Package.FileList.append((ToFile, Md5Sum))\r
588 elif Package:\r
589 continue\r
590 elif (ToFile, Md5Sum) not in Module.FileList:\r
591 Module.FileList.append((ToFile, Md5Sum)) \r
592 \r
593 ModuleList.append((Module, Package))\r
594\r
595## FileUnderPath\r
596# Check whether FileName started with directory specified by CheckPath \r
597#\r
598# @param FileName: the FileName need to be checked\r
599# @param CheckPath: the path need to be checked against\r
600# @return: True or False \r
601#\r
602def FileUnderPath(FileName, CheckPath):\r
603 FileName = FileName.replace('\\', '/')\r
604 FileName = os.path.normpath(FileName)\r
605 CheckPath = CheckPath.replace('\\', '/')\r
606 CheckPath = os.path.normpath(CheckPath)\r
607 if FileName.startswith(CheckPath):\r
608 RemainingPath = os.path.normpath(FileName.replace(CheckPath, '', 1))\r
609 while RemainingPath.startswith('\\') or RemainingPath.startswith('/'):\r
610 RemainingPath = RemainingPath[1:]\r
611 if FileName == os.path.normpath(os.path.join(CheckPath, RemainingPath)):\r
612 return True\r
613 \r
614 return False\r
615\r
616## InstallFile\r
617# Extract File from Zipfile, set file attribute, and return the Md5Sum\r
618#\r
619# @return: True or False \r
620#\r
621def InstallFile(ContentZipFile, FromFile, ToFile, ReadOnly, Executable=False):\r
622 if not ContentZipFile or not ContentZipFile.UnpackFile(FromFile, ToFile):\r
623 Logger.Error("UPT", FILE_NOT_FOUND, ST.ERR_INSTALL_FILE_FROM_EMPTY_CONTENT%FromFile)\r
624\r
625 if ReadOnly:\r
626 if not Executable:\r
627 chmod(ToFile, stat.S_IREAD)\r
628 else:\r
629 chmod(ToFile, stat.S_IREAD|stat.S_IEXEC)\r
630 elif Executable:\r
631 chmod(ToFile, stat.S_IREAD|stat.S_IWRITE|stat.S_IEXEC)\r
632 else:\r
633 chmod(ToFile, stat.S_IREAD|stat.S_IWRITE)\r
634 \r
635 Md5Sigature = md5.new(open(str(ToFile), 'rb').read())\r
636 Md5Sum = Md5Sigature.hexdigest()\r
637 return Md5Sum\r
638 \r
639## InstallPackageContent method\r
640#\r
641# @param FromPath: FromPath\r
642# @param ToPath: ToPath\r
643# @param Package: Package\r
644# @param ContentZipFile: ContentZipFile\r
645# @param Dep: Dep\r
646# @param WorkspaceDir: WorkspaceDir\r
647# @param ModuleList: ModuleList\r
648#\r
649def InstallPackageContent(FromPath, ToPath, Package, ContentZipFile, Dep,\r
650 WorkspaceDir, ModuleList, ReadOnly = False):\r
651 if Dep:\r
652 pass\r
653 Package.FileList = []\r
654 \r
655 if ToPath.startswith("\\") or ToPath.startswith("/"):\r
656 ToPath = ToPath[1:]\r
657 \r
658 if not IsValidInstallPath(ToPath):\r
659 Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%ToPath) \r
660\r
661 if FromPath.startswith("\\") or FromPath.startswith("/"):\r
662 FromPath = FromPath[1:]\r
663 \r
664 if not IsValidInstallPath(FromPath):\r
665 Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%FromPath) \r
666 \r
667 PackageFullPath = os.path.normpath(os.path.join(WorkspaceDir, ToPath))\r
668 for MiscFile in Package.GetMiscFileList():\r
669 for Item in MiscFile.GetFileList():\r
670 FileName = Item.GetURI()\r
671 if FileName.startswith("\\") or FileName.startswith("/"):\r
672 FileName = FileName[1:]\r
673 \r
674 if not IsValidInstallPath(FileName):\r
675 Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%FileName)\r
676 \r
677 FromFile = os.path.join(FromPath, FileName)\r
678 Executable = Item.GetExecutable()\r
679 ToFile = (os.path.join(PackageFullPath, ConvertPath(FileName)))\r
680 Md5Sum = InstallFile(ContentZipFile, FromFile, ToFile, ReadOnly, Executable)\r
681 if (ToFile, Md5Sum) not in Package.FileList:\r
682 Package.FileList.append((ToFile, Md5Sum))\r
683 PackageIncludeArchList = [] \r
684 for Item in Package.GetPackageIncludeFileList():\r
685 FileName = Item.GetFilePath()\r
686 if FileName.startswith("\\") or FileName.startswith("/"):\r
687 FileName = FileName[1:]\r
688 \r
689 if not IsValidInstallPath(FileName):\r
690 Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%FileName) \r
691 \r
692 FromFile = os.path.join(FromPath, FileName)\r
693 ToFile = os.path.normpath(os.path.join(PackageFullPath, ConvertPath(FileName)))\r
694 RetFile = ContentZipFile.UnpackFile(FromFile, ToFile)\r
695 if RetFile == '':\r
696 #\r
697 # a non-exist path in Zipfile will return '', which means an include directory in our case\r
698 # save the information for later DEC creation usage and also create the directory\r
699 #\r
700 PackageIncludeArchList.append([Item.GetFilePath(), Item.GetSupArchList()])\r
701 CreateDirectory(ToFile)\r
702 continue\r
703 if ReadOnly:\r
704 chmod(ToFile, stat.S_IREAD)\r
705 else:\r
706 chmod(ToFile, stat.S_IREAD|stat.S_IWRITE) \r
707 Md5Sigature = md5.new(open(str(ToFile), 'rb').read())\r
708 Md5Sum = Md5Sigature.hexdigest()\r
709 if (ToFile, Md5Sum) not in Package.FileList:\r
710 Package.FileList.append((ToFile, Md5Sum))\r
711 Package.SetIncludeArchList(PackageIncludeArchList)\r
712 \r
713 for Item in Package.GetStandardIncludeFileList():\r
714 FileName = Item.GetFilePath()\r
715 if FileName.startswith("\\") or FileName.startswith("/"):\r
716 FileName = FileName[1:]\r
717 \r
718 if not IsValidInstallPath(FileName):\r
719 Logger.Error("UPT", FORMAT_INVALID, ST.ERR_FILE_NAME_INVALIDE%FileName) \r
720 \r
721 FromFile = os.path.join(FromPath, FileName)\r
722 ToFile = os.path.normpath(os.path.join(PackageFullPath, ConvertPath(FileName)))\r
723 Md5Sum = InstallFile(ContentZipFile, FromFile, ToFile, ReadOnly)\r
724 if (ToFile, Md5Sum) not in Package.FileList:\r
725 Package.FileList.append((ToFile, Md5Sum))\r
726\r
727 #\r
728 # Update package\r
729 #\r
730 Package.SetPackagePath(Package.GetPackagePath().replace(FromPath,\r
731 ToPath, 1))\r
732 Package.SetFullPath(os.path.normpath(os.path.join(PackageFullPath,\r
733 ConvertPath(Package.GetName()) + '.dec')))\r
734\r
735 #\r
736 # Install files in module\r
737 #\r
738 Module = None\r
739 ModuleDict = Package.GetModuleDict()\r
d0acc87a
LG
740 for ModuleGuid, ModuleVersion, ModuleName, ModulePath in ModuleDict:\r
741 Module = ModuleDict[ModuleGuid, ModuleVersion, ModuleName, ModulePath]\r
4234283c
LG
742 InstallModuleContent(FromPath, ToPath, ModulePath, Module,\r
743 ContentZipFile, WorkspaceDir, ModuleList, Package, ReadOnly)\r
744\r
745## GetDPFile method\r
746#\r
747# @param ZipFile: A ZipFile\r
748#\r
749def GetDPFile(ZipFile):\r
750 ContentFile = ''\r
751 DescFile = ''\r
752 for FileName in ZipFile.namelist():\r
753 if FileName.endswith('.content'):\r
754 if not ContentFile:\r
755 ContentFile = FileName\r
756 continue\r
757 elif FileName.endswith('.pkg'):\r
758 if not DescFile:\r
759 DescFile = FileName\r
760 continue\r
761 else:\r
762 continue\r
763 \r
764 Logger.Error("PackagingTool", FILE_TYPE_MISMATCH,\r
765 ExtraData=ST.ERR_DIST_FILE_TOOMANY)\r
766 if not DescFile or not ContentFile:\r
767 Logger.Error("PackagingTool", FILE_UNKNOWN_ERROR,\r
768 ExtraData=ST.ERR_DIST_FILE_TOOFEW)\r
769 return DescFile, ContentFile\r
770\r