2929import java .util .Map ;
3030import java .util .UUID ;
3131
32+ import com .cloud .agent .api .storage .*;
33+ import com .cloud .agent .api .to .*;
34+ import org .apache .cloudstack .storage .to .TemplateObjectTO ;
35+ import org .apache .cloudstack .storage .to .VolumeObjectTO ;
3236import org .apache .log4j .Logger ;
3337
3438import com .cloud .agent .api .Answer ;
4448import com .cloud .agent .api .DeleteVMSnapshotCommand ;
4549import com .cloud .agent .api .RevertToVMSnapshotAnswer ;
4650import com .cloud .agent .api .RevertToVMSnapshotCommand ;
47- import com .cloud .agent .api .storage .CopyVolumeAnswer ;
48- import com .cloud .agent .api .storage .CopyVolumeCommand ;
49- import com .cloud .agent .api .storage .PrepareOVAPackingAnswer ;
50- import com .cloud .agent .api .storage .PrepareOVAPackingCommand ;
51- import com .cloud .agent .api .storage .CreateVolumeOVAAnswer ;
52- import com .cloud .agent .api .storage .CreateVolumeOVACommand ;
53- import com .cloud .agent .api .storage .CreatePrivateTemplateAnswer ;
54- import com .cloud .agent .api .storage .PrimaryStorageDownloadAnswer ;
55- import com .cloud .agent .api .storage .PrimaryStorageDownloadCommand ;
56- import com .cloud .agent .api .to .StorageFilerTO ;
57- import com .cloud .agent .api .to .VolumeTO ;
5851import com .cloud .hypervisor .vmware .mo .CustomFieldConstants ;
5952import com .cloud .hypervisor .vmware .mo .DatacenterMO ;
6053import com .cloud .hypervisor .vmware .mo .DatastoreMO ;
8982import com .vmware .vim25 .VirtualSCSISharing ;
9083
9184public class VmwareStorageManagerImpl implements VmwareStorageManager {
85+ @ Override
86+ public boolean execute (VmwareHostService hostService , CreateEntityDownloadURLCommand cmd ) {
87+ DataTO data = cmd .getData ();
88+ if (data == null ) {
89+ return false ;
90+ }
91+
92+ String newPath = null ;
93+ if (data .getObjectType () == DataObjectType .VOLUME ) {
94+ newPath = createOvaForVolume ((VolumeObjectTO )data );
95+ } else if (data .getObjectType () == DataObjectType .TEMPLATE ) {
96+ newPath = createOvaForTemplate ((TemplateObjectTO )data );
97+ }
98+ if (newPath != null ) {
99+ cmd .setInstallPath (newPath );
100+ }
101+ return true ;
102+ }
103+
92104 private static final Logger s_logger = Logger .getLogger (VmwareStorageManagerImpl .class );
93105
94106 private final VmwareStorageMount _mountService ;
@@ -108,108 +120,89 @@ public void configure(Map<String, Object> params) {
108120 _timeout = NumbersUtil .parseInt (value , 1440 ) * 1000 ;
109121 }
110122
111- //Fang note: use Answer here instead of the PrepareOVAPackingAnswer
112- @ Override
113- public Answer execute (VmwareHostService hostService , PrepareOVAPackingCommand cmd ) {
114- String secStorageUrl = ((PrepareOVAPackingCommand ) cmd ).getSecondaryStorageUrl ();
115- assert (secStorageUrl != null );
116- String installPath = cmd .getTemplatePath ();
117- String details = null ;
118- boolean success = false ;
119- String ovafileName = "" ;
120- s_logger .info ("Fang: execute OVAPacking cmd at vmwareMngImpl. " );
121- String secondaryMountPoint = _mountService .getMountPoint (secStorageUrl );
122- // String installPath = getTemplateRelativeDirInSecStorage(accountId, templateId);
123- String installFullPath = secondaryMountPoint + "/" + installPath ;
124-
125- String templateName = installFullPath ; // should be a file ending .ova;
126- s_logger .info ("Fang: execute vmwareMgrImpl: templateNAme " + templateName );
127- // Fang: Dir list, if there is ova file, done; Fang: add answer cmd;
128- // if not, from ova.meta, create a new OVA file;
129- // change the install path to *.ova , not ova.meta;
130- // VmwareContext context = hostService.getServiceContext(cmd); //Fang: we may not have the CTX here
131- try {
132- if (templateName .endsWith (".ova" )) {
133- if (new File (templateName ).exists ()) {
134- details = "OVA files exists. succeed. " ;
135- return new Answer (cmd , true , details );
136- } else {
137- if (new File (templateName + ".meta" ).exists ()) { //Fang parse the meta file
138- //execute the tar command;
139- s_logger .info ("Fang: execute vmwareMgrImpl: getfromMeta " + templateName );
140- ovafileName = getOVAFromMetafile (templateName + ".meta" );
141- details = "OVA file in meta file is " + ovafileName ;
142- return new Answer (cmd , true , details );
143- } else {
144- String msg = "Unable to find ova meta or ova file to prepare template (vmware)" ;
145- s_logger .error (msg );
146- throw new Exception (msg );
147- }
148- }
149- }
150- } catch (Throwable e ) {
151- if (e instanceof RemoteException ) {
152- //hostService.invalidateServiceContext(context); do not need context
153- s_logger .error ("Unable to connect to remote service " );
154- details = "Unable to connect to remote service " ;
155- return new Answer (cmd , false , details );
156- }
157- String msg = "Unable to execute PrepareOVAPackingCommand due to exception" ;
158- s_logger .error (msg , e );
159- return new Answer (cmd , false , details );
123+ public String createOvaForTemplate (TemplateObjectTO template ) {
124+ DataStoreTO storeTO = template .getDataStore ();
125+ if (!(storeTO instanceof NfsTO )) {
126+ s_logger .debug ("can only handle nfs storage, when create ova from volume" );
127+ return null ;
128+ }
129+ NfsTO nfsStore = (NfsTO )storeTO ;
130+ String secStorageUrl = nfsStore .getUrl ();
131+ assert (secStorageUrl != null );
132+ String installPath = template .getPath ();
133+ String ovafileName = "" ;
134+ String secondaryMountPoint = _mountService .getMountPoint (secStorageUrl );
135+ String installFullPath = secondaryMountPoint + "/" + installPath ;
136+
137+ String templateName = installFullPath ; // should be a file ending .ova;
138+ try {
139+ if (templateName .endsWith (".ova" )) {
140+ if (new File (templateName ).exists ()) {
141+ s_logger .debug ("OVA files exists. succeed. " );
142+ return templateName ;
143+ } else {
144+ if (new File (templateName + ".meta" ).exists ()) {
145+ ovafileName = getOVAFromMetafile (templateName + ".meta" );
146+ s_logger .debug ("OVA file in meta file is " + ovafileName );
147+ return installPath ;
148+ } else {
149+ String msg = "Unable to find ova meta or ova file to prepare template (vmware)" ;
150+ s_logger .error (msg );
151+ throw new Exception (msg );
152+ }
153+ }
160154 }
161- return new Answer (cmd , true , details );
155+ } catch (Throwable e ) {
156+ s_logger .debug ("Failed to create ova: " + e .toString ());
157+ }
158+ return null ;
162159 }
163160
164161 //Fang: new command added;
165162 // Important! we need to sync file system before we can safely use tar to work around a linux kernal bug(or feature)
166- @ Override
167- public Answer execute (VmwareHostService hostService , CreateVolumeOVACommand cmd ) {
168- String secStorageUrl = ((CreateVolumeOVACommand ) cmd ).getSecondaryStorageUrl ();
169- assert (secStorageUrl != null );
170- String installPath = cmd .getVolPath ();
163+ public String createOvaForVolume (VolumeObjectTO volume ) {
164+ DataStoreTO storeTO = volume .getDataStore ();
165+ if (!(storeTO instanceof NfsTO )) {
166+ s_logger .debug ("can only handle nfs storage, when create ova from volume" );
167+ return null ;
168+ }
169+ NfsTO nfsStore = (NfsTO )storeTO ;
170+ String secStorageUrl = nfsStore .getUrl ();
171+ assert (secStorageUrl != null );
172+ //Note the volume path is volumes/accountId/volumeId/uuid/, the actual volume is uuid/uuid.vmdk
173+ String installPath = volume .getPath ();
174+ int index = installPath .lastIndexOf (File .separator );
175+ String volumeUuid = installPath .substring (index + 1 );
171176 String details = null ;
172- boolean success = false ;
177+ boolean success = false ;
173178
174- s_logger .info ("volss: execute CreateVolumeOVA cmd at vmwareMngImpl. " );
175- String secondaryMountPoint = _mountService .getMountPoint (secStorageUrl );
176- // String installPath = getTemplateRelativeDirInSecStorage(accountId, templateId);
177- s_logger .info ("volss: mountPoint: " + secondaryMountPoint + "installPath:" + installPath );
178- String installFullPath = secondaryMountPoint + "/" + installPath ;
179-
180- String volName = cmd .getVolName (); // should be a UUID, without ova ovf, etc;
181- s_logger .info ("volss: execute vmwareMgrImpl: VolName " + volName );
182- // Fang: Dir list, if there is ova file, done; Note: add answer cmd;
183-
184- try {
185- if (new File (volName + ".ova" ).exists ()) {
186- details = "OVA files exists. succeed. " ;
187- return new CreateVolumeOVAAnswer (cmd , true , details );
188- } else {
189- File ovaFile = new File (installFullPath );
190- String exportDir = ovaFile .getParent ();
191-
192- s_logger .info ("Fang: exportDir is (for VolumeOVA): " + exportDir );
193- s_logger .info ("Sync file system before we package OVA..." );
194-
195- Script commandSync = new Script (true , "sync" , 0 , s_logger );
196- commandSync .execute ();
197-
198- Script command = new Script (false , "tar" , 0 , s_logger );
199- command .setWorkDir (exportDir );
200- command .add ("-cf" , volName + ".ova" );
201- command .add (volName + ".ovf" ); // OVF file should be the first file in OVA archive
202- command .add (volName + "-disk0.vmdk" );
203-
204- s_logger .info ("Package Volume OVA with commmand: " + command .toString ());
205- command .execute ();
206- return new CreateVolumeOVAAnswer (cmd , true , details );
207- }
208- } catch (Throwable e ) {
209- s_logger .info ("Exception for createVolumeOVA" );
210- }
211- return new CreateVolumeOVAAnswer (cmd , true , "fail to pack OVA for volume" );
212- }
179+ String secondaryMountPoint = _mountService .getMountPoint (secStorageUrl );
180+ //The real volume path
181+ String volumePath = installPath + File .separator + volumeUuid + ".ova" ;
182+ String installFullPath = secondaryMountPoint + "/" + installPath ;
183+
184+ try {
185+ if (new File (secondaryMountPoint + File .separator + volumePath ).exists ()) {
186+ s_logger .debug ("ova already exists:" + volumePath );
187+ return volumePath ;
188+ } else {
189+ Script commandSync = new Script (true , "sync" , 0 , s_logger );
190+ commandSync .execute ();
191+
192+ Script command = new Script (false , "tar" , 0 , s_logger );
193+ command .setWorkDir (installFullPath );
194+ command .add ("-cf" , volumeUuid + ".ova" );
195+ command .add (volumeUuid + ".ovf" ); // OVF file should be the first file in OVA archive
196+ command .add (volumeUuid + "-disk0.vmdk" );
197+
198+ command .execute ();
199+ return volumePath ;
200+ }
201+ } catch (Throwable e ) {
202+ s_logger .info ("Exception for createVolumeOVA" );
203+ }
204+ return null ;
205+ }
213206
214207 @ Override
215208 public Answer execute (VmwareHostService hostService , PrimaryStorageDownloadCommand cmd ) {
0 commit comments