Changeset 65807 in vbox for trunk/src/VBox/Main/src-server/ApplianceImplExport.cpp
- Timestamp:
- Feb 20, 2017 10:28:47 AM (8 years ago)
- svn:sync-xref-src-repo-rev:
- 113542
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Main/src-server/ApplianceImplExport.cpp
r65530 r65807 905 905 // might have UUIDs that need fixing after we know the UUIDs of the exported images 906 906 std::list<xml::ElementNode*> llElementsWithUuidAttributes; 907 907 uint32_t ulFile = 1; 908 908 list< ComObjPtr<VirtualSystemDescription> >::const_iterator it; 909 909 /* Iterate through all virtual systems of that appliance */ … … 919 919 enFormat, 920 920 stack); // disks and networks stack 921 922 list<Utf8Str> diskList; 923 list<Utf8Str>::const_iterator itS; 924 925 for (itS = stack.mapDiskSequenceForOneVM.begin(); 926 itS != stack.mapDiskSequenceForOneVM.end(); 927 ++itS) 928 { 929 const Utf8Str &strDiskID = *itS; 930 const VirtualSystemDescriptionEntry *pDiskEntry = stack.mapDisks[strDiskID]; 931 932 // source path: where the VBox image is 933 const Utf8Str &strSrcFilePath = pDiskEntry->strVBoxCurrent; 934 Bstr bstrSrcFilePath(strSrcFilePath); 935 936 //skip empty Medium. There are no information to add into section <References> or <DiskSection> 937 if (strSrcFilePath.isEmpty() || 938 pDiskEntry->skipIt == true) 939 continue; 940 941 // Do NOT check here whether the file exists. FindMedium will figure 942 // that out, and filesystem-based tests are simply wrong in the 943 // general case (think of iSCSI). 944 945 // We need some info from the source disks 946 ComPtr<IMedium> pSourceDisk; 947 //DeviceType_T deviceType = DeviceType_HardDisk;// by default 948 949 Log(("Finding source disk \"%ls\"\n", bstrSrcFilePath.raw())); 950 951 HRESULT rc; 952 953 if (pDiskEntry->type == VirtualSystemDescriptionType_HardDiskImage) 954 { 955 rc = mVirtualBox->OpenMedium(bstrSrcFilePath.raw(), 956 DeviceType_HardDisk, 957 AccessMode_ReadWrite, 958 FALSE /* fForceNewUuid */, 959 pSourceDisk.asOutParam()); 960 if (FAILED(rc)) 961 throw rc; 962 } 963 else if (pDiskEntry->type == VirtualSystemDescriptionType_CDROM)//may be, this is CD/DVD 964 { 965 rc = mVirtualBox->OpenMedium(bstrSrcFilePath.raw(), 966 DeviceType_DVD, 967 AccessMode_ReadOnly, 968 FALSE, 969 pSourceDisk.asOutParam()); 970 if (FAILED(rc)) 971 throw rc; 972 } 973 974 Bstr uuidSource; 975 rc = pSourceDisk->COMGETTER(Id)(uuidSource.asOutParam()); 976 if (FAILED(rc)) throw rc; 977 Guid guidSource(uuidSource); 978 979 // output filename 980 const Utf8Str &strTargetFileNameOnly = pDiskEntry->strOvf; 981 // target path needs to be composed from where the output OVF is 982 Utf8Str strTargetFilePath(strPath); 983 strTargetFilePath.stripFilename(); 984 strTargetFilePath.append("/"); 985 strTargetFilePath.append(strTargetFileNameOnly); 986 987 // We are always exporting to VMDK stream optimized for now 988 //Bstr bstrSrcFormat = L"VMDK";//not used 989 990 diskList.push_back(strTargetFilePath); 991 992 LONG64 cbCapacity = 0; // size reported to guest 993 rc = pSourceDisk->COMGETTER(LogicalSize)(&cbCapacity); 994 if (FAILED(rc)) throw rc; 995 /// @todo r=poetzsch: wrong it is reported in bytes ... 996 // capacity is reported in megabytes, so... 997 //cbCapacity *= _1M; 998 999 Guid guidTarget; /* Creates a new uniq number for the target disk. */ 1000 guidTarget.create(); 1001 1002 // now handle the XML for the disk: 1003 Utf8StrFmt strFileRef("file%RI32", ulFile++); 1004 // <File ovf:href="WindowsXpProfessional-disk1.vmdk" ovf:id="file1" ovf:size="1710381056"/> 1005 xml::ElementNode *pelmFile = pelmReferences->createChild("File"); 1006 pelmFile->setAttribute("ovf:id", strFileRef); 1007 pelmFile->setAttribute("ovf:href", strTargetFileNameOnly); 1008 /// @todo the actual size is not available at this point of time, 1009 // cause the disk will be compressed. The 1.0 standard says this is 1010 // optional! 1.1 isn't fully clear if the "gzip" format is used. 1011 // Need to be checked. */ 1012 // pelmFile->setAttribute("ovf:size", Utf8StrFmt("%RI64", cbFile).c_str()); 1013 1014 // add disk to XML Disks section 1015 // <Disk ovf:capacity="8589934592" ovf:diskId="vmdisk1" ovf:fileRef="file1" ovf:format="..."/> 1016 xml::ElementNode *pelmDisk = pelmDiskSection->createChild("Disk"); 1017 pelmDisk->setAttribute("ovf:capacity", Utf8StrFmt("%RI64", cbCapacity).c_str()); 1018 pelmDisk->setAttribute("ovf:diskId", strDiskID); 1019 pelmDisk->setAttribute("ovf:fileRef", strFileRef); 1020 1021 if (pDiskEntry->type == VirtualSystemDescriptionType_HardDiskImage)//deviceType == DeviceType_HardDisk 1022 { 1023 pelmDisk->setAttribute("ovf:format", 1024 (enFormat == ovf::OVFVersion_0_9) 1025 ? "http://www.vmware.com/specifications/vmdk.html#sparse" // must be sparse or ovftoo 1026 : "http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized" 1027 // correct string as communicated to us by VMware (public bug #6612) 1028 ); 1029 } 1030 else //pDiskEntry->type == VirtualSystemDescriptionType_CDROM, deviceType == DeviceType_DVD 1031 { 1032 pelmDisk->setAttribute("ovf:format", 1033 "http://www.ecma-international.org/publications/standards/Ecma-119.htm" 1034 ); 1035 } 1036 1037 // add the UUID of the newly target image to the OVF disk element, but in the 1038 // vbox: namespace since it's not part of the standard 1039 pelmDisk->setAttribute("vbox:uuid", Utf8StrFmt("%RTuuid", guidTarget.raw()).c_str()); 1040 1041 // now, we might have other XML elements from vbox:Machine pointing to this image, 1042 // but those would refer to the UUID of the _source_ image (which we created the 1043 // export image from); those UUIDs need to be fixed to the export image 1044 Utf8Str strGuidSourceCurly = guidSource.toStringCurly(); 1045 for (std::list<xml::ElementNode*>::iterator eit = llElementsWithUuidAttributes.begin(); 1046 eit != llElementsWithUuidAttributes.end(); 1047 ++eit) 1048 { 1049 xml::ElementNode *pelmImage = *eit; 1050 Utf8Str strUUID; 1051 pelmImage->getAttributeValue("uuid", strUUID); 1052 if (strUUID == strGuidSourceCurly) 1053 // overwrite existing uuid attribute 1054 pelmImage->setAttribute("uuid", guidTarget.toStringCurly()); 1055 } 1056 } 1057 llElementsWithUuidAttributes.clear(); 1058 stack.mapDiskSequenceForOneVM.clear(); 921 1059 } 922 1060 … … 934 1072 } 935 1073 936 // Finally, write out the disk info937 list<Utf8Str> diskList;938 uint32_t ulFile = 1;939 list<Utf8Str>::const_iterator itS;940 941 for (itS = stack.mapDiskSequence.begin();942 itS != stack.mapDiskSequence.end();943 ++itS)944 {945 const Utf8Str &strDiskID = *itS;946 const VirtualSystemDescriptionEntry *pDiskEntry = stack.mapDisks[strDiskID];947 948 // source path: where the VBox image is949 const Utf8Str &strSrcFilePath = pDiskEntry->strVBoxCurrent;950 Bstr bstrSrcFilePath(strSrcFilePath);951 952 //skip empty Medium. There are no information to add into section <References> or <DiskSection>953 if (strSrcFilePath.isEmpty() ||954 pDiskEntry->skipIt == true)955 continue;956 957 // Do NOT check here whether the file exists. FindMedium will figure958 // that out, and filesystem-based tests are simply wrong in the959 // general case (think of iSCSI).960 961 // We need some info from the source disks962 ComPtr<IMedium> pSourceDisk;963 //DeviceType_T deviceType = DeviceType_HardDisk;// by default964 965 Log(("Finding source disk \"%ls\"\n", bstrSrcFilePath.raw()));966 967 HRESULT rc;968 969 if (pDiskEntry->type == VirtualSystemDescriptionType_HardDiskImage)970 {971 rc = mVirtualBox->OpenMedium(bstrSrcFilePath.raw(),972 DeviceType_HardDisk,973 AccessMode_ReadWrite,974 FALSE /* fForceNewUuid */,975 pSourceDisk.asOutParam());976 if (FAILED(rc))977 throw rc;978 }979 else if (pDiskEntry->type == VirtualSystemDescriptionType_CDROM)//may be, this is CD/DVD980 {981 rc = mVirtualBox->OpenMedium(bstrSrcFilePath.raw(),982 DeviceType_DVD,983 AccessMode_ReadOnly,984 FALSE,985 pSourceDisk.asOutParam());986 if (FAILED(rc))987 throw rc;988 }989 990 Bstr uuidSource;991 rc = pSourceDisk->COMGETTER(Id)(uuidSource.asOutParam());992 if (FAILED(rc)) throw rc;993 Guid guidSource(uuidSource);994 995 // output filename996 const Utf8Str &strTargetFileNameOnly = pDiskEntry->strOvf;997 // target path needs to be composed from where the output OVF is998 Utf8Str strTargetFilePath(strPath);999 strTargetFilePath.stripFilename();1000 strTargetFilePath.append("/");1001 strTargetFilePath.append(strTargetFileNameOnly);1002 1003 // We are always exporting to VMDK stream optimized for now1004 //Bstr bstrSrcFormat = L"VMDK";//not used1005 1006 diskList.push_back(strTargetFilePath);1007 1008 LONG64 cbCapacity = 0; // size reported to guest1009 rc = pSourceDisk->COMGETTER(LogicalSize)(&cbCapacity);1010 if (FAILED(rc)) throw rc;1011 /// @todo r=poetzsch: wrong it is reported in bytes ...1012 // capacity is reported in megabytes, so...1013 //cbCapacity *= _1M;1014 1015 Guid guidTarget; /* Creates a new uniq number for the target disk. */1016 guidTarget.create();1017 1018 // now handle the XML for the disk:1019 Utf8StrFmt strFileRef("file%RI32", ulFile++);1020 // <File ovf:href="WindowsXpProfessional-disk1.vmdk" ovf:id="file1" ovf:size="1710381056"/>1021 xml::ElementNode *pelmFile = pelmReferences->createChild("File");1022 pelmFile->setAttribute("ovf:id", strFileRef);1023 pelmFile->setAttribute("ovf:href", strTargetFileNameOnly);1024 /// @todo the actual size is not available at this point of time,1025 // cause the disk will be compressed. The 1.0 standard says this is1026 // optional! 1.1 isn't fully clear if the "gzip" format is used.1027 // Need to be checked. */1028 // pelmFile->setAttribute("ovf:size", Utf8StrFmt("%RI64", cbFile).c_str());1029 1030 // add disk to XML Disks section1031 // <Disk ovf:capacity="8589934592" ovf:diskId="vmdisk1" ovf:fileRef="file1" ovf:format="..."/>1032 xml::ElementNode *pelmDisk = pelmDiskSection->createChild("Disk");1033 pelmDisk->setAttribute("ovf:capacity", Utf8StrFmt("%RI64", cbCapacity).c_str());1034 pelmDisk->setAttribute("ovf:diskId", strDiskID);1035 pelmDisk->setAttribute("ovf:fileRef", strFileRef);1036 1037 if (pDiskEntry->type == VirtualSystemDescriptionType_HardDiskImage)//deviceType == DeviceType_HardDisk1038 {1039 pelmDisk->setAttribute("ovf:format",1040 (enFormat == ovf::OVFVersion_0_9)1041 ? "http://www.vmware.com/specifications/vmdk.html#sparse" // must be sparse or ovftool ch1042 : "http://www.vmware.com/interfaces/specifications/vmdk.html#streamOptimized"1043 // correct string as communicated to us by VMware (public bug #6612)1044 );1045 }1046 else //pDiskEntry->type == VirtualSystemDescriptionType_CDROM, deviceType == DeviceType_DVD1047 {1048 pelmDisk->setAttribute("ovf:format",1049 "http://www.ecma-international.org/publications/standards/Ecma-119.htm"1050 );1051 }1052 1053 // add the UUID of the newly target image to the OVF disk element, but in the1054 // vbox: namespace since it's not part of the standard1055 pelmDisk->setAttribute("vbox:uuid", Utf8StrFmt("%RTuuid", guidTarget.raw()).c_str());1056 1057 // now, we might have other XML elements from vbox:Machine pointing to this image,1058 // but those would refer to the UUID of the _source_ image (which we created the1059 // export image from); those UUIDs need to be fixed to the export image1060 Utf8Str strGuidSourceCurly = guidSource.toStringCurly();1061 for (std::list<xml::ElementNode*>::iterator eit = llElementsWithUuidAttributes.begin();1062 eit != llElementsWithUuidAttributes.end();1063 ++eit)1064 {1065 xml::ElementNode *pelmImage = *eit;1066 Utf8Str strUUID;1067 pelmImage->getAttributeValue("uuid", strUUID);1068 if (strUUID == strGuidSourceCurly)1069 // overwrite existing uuid attribute1070 pelmImage->setAttribute("uuid", guidTarget.toStringCurly());1071 }1072 }1073 1074 } 1074 1075 … … 1553 1554 //in the OVF description file. 1554 1555 stack.mapDiskSequence.push_back(strDiskID); 1556 stack.mapDiskSequenceForOneVM.push_back(strDiskID); 1555 1557 } 1556 1558 break; … … 1629 1631 //in the OVF description file. 1630 1632 stack.mapDiskSequence.push_back(strDiskID); 1633 stack.mapDiskSequenceForOneVM.push_back(strDiskID); 1631 1634 // there is no DVD drive map to update because it is 1632 1635 // handled completely with this entry.
Note:
See TracChangeset
for help on using the changeset viewer.