|
53 | 53 | import org.apache.cloudstack.storage.command.DownloadCommand; |
54 | 54 | import org.apache.cloudstack.storage.command.DownloadProgressCommand; |
55 | 55 | import org.apache.cloudstack.storage.command.DownloadCommand.ResourceType; |
| 56 | +import org.apache.cloudstack.storage.to.SnapshotObjectTO; |
56 | 57 | import org.apache.cloudstack.storage.to.TemplateObjectTO; |
57 | 58 | import org.apache.commons.lang.StringUtils; |
58 | 59 | import org.apache.log4j.Logger; |
|
103 | 104 | import com.cloud.exception.InternalErrorException; |
104 | 105 | import com.cloud.host.Host; |
105 | 106 | import com.cloud.host.Host.Type; |
| 107 | +import com.cloud.hypervisor.Hypervisor.HypervisorType; |
106 | 108 | import com.cloud.resource.ServerResourceBase; |
107 | 109 | import com.cloud.storage.DataStoreRole; |
108 | 110 | import com.cloud.storage.StorageLayer; |
109 | 111 | import com.cloud.storage.VMTemplateStorageResourceAssoc.Status; |
110 | 112 | import com.cloud.storage.template.DownloadManager; |
111 | 113 | import com.cloud.storage.template.DownloadManagerImpl; |
112 | 114 | import com.cloud.storage.template.DownloadManagerImpl.ZfsPathParser; |
| 115 | +import com.cloud.storage.template.Processor.FormatInfo; |
| 116 | +import com.cloud.storage.template.Processor; |
| 117 | +import com.cloud.storage.template.QCOW2Processor; |
113 | 118 | import com.cloud.storage.template.TemplateLocation; |
114 | 119 | import com.cloud.storage.template.TemplateProp; |
115 | 120 | import com.cloud.storage.template.UploadManager; |
116 | 121 | import com.cloud.storage.template.UploadManagerImpl; |
| 122 | +import com.cloud.storage.template.VhdProcessor; |
117 | 123 | import com.cloud.utils.NumbersUtil; |
118 | 124 | import com.cloud.utils.S3Utils; |
119 | 125 | import com.cloud.utils.S3Utils.FileNamingStrategy; |
@@ -161,6 +167,7 @@ public class NfsSecondaryStorageResource extends ServerResourceBase implements S |
161 | 167 | final private String _parent = "/mnt/SecStorage"; |
162 | 168 | final private String _tmpltDir = "/var/cloudstack/template"; |
163 | 169 | final private String _tmpltpp = "template.properties"; |
| 170 | + private String createTemplateFromSnapshotXenScript; |
164 | 171 |
|
165 | 172 | @Override |
166 | 173 | public void disconnected() { |
@@ -280,35 +287,103 @@ public String determineFileName(final String key) { |
280 | 287 | return new CopyCmdAnswer(errMsg); |
281 | 288 | } |
282 | 289 | } |
| 290 | + |
| 291 | + |
| 292 | + protected Answer copySnapshotToTemplateFromNfsToNfsXenserver(CopyCommand cmd, SnapshotObjectTO srcData, NfsTO srcDataStore, TemplateObjectTO destData, NfsTO destDataStore) { |
| 293 | + String srcMountPoint = this.getRootDir(srcDataStore.getUrl()); |
| 294 | + String snapshotPath = srcData.getPath(); |
| 295 | + int index = snapshotPath.lastIndexOf("/"); |
| 296 | + String snapshotName = snapshotPath.substring(index + 1); |
| 297 | + if (!snapshotName.startsWith("VHD-") && !snapshotName.endsWith(".vhd")) { |
| 298 | + snapshotName = snapshotName + ".vhd"; |
| 299 | + } |
| 300 | + snapshotPath = snapshotPath.substring(0, index); |
| 301 | + snapshotPath = srcMountPoint + snapshotPath; |
| 302 | + String destMountPoint = this.getRootDir(destDataStore.getUrl()); |
| 303 | + String destPath = destMountPoint + destData.getPath(); |
283 | 304 |
|
284 | | - protected Answer copyFromSwiftToNfs(CopyCommand cmd, DataTO srcData, SwiftTO srcImageStore, |
| 305 | + String errMsg = null; |
| 306 | + try { |
| 307 | + this._storage.mkdir(destPath); |
| 308 | + |
| 309 | + String templateUuid = UUID.randomUUID().toString(); |
| 310 | + String templateName = templateUuid + ".vhd"; |
| 311 | + Script command = new Script(this.createTemplateFromSnapshotXenScript, cmd.getWait(), s_logger); |
| 312 | + command.add("-p", snapshotPath); |
| 313 | + command.add("-s", snapshotName); |
| 314 | + command.add("-n", templateName); |
| 315 | + command.add("-t", destPath); |
| 316 | + command.execute(); |
| 317 | + |
| 318 | + Map<String, Object> params = new HashMap<String, Object>(); |
| 319 | + params.put(StorageLayer.InstanceConfigKey, _storage); |
| 320 | + Processor processor = new VhdProcessor(); |
| 321 | + |
| 322 | + processor.configure("Vhd Processor", params); |
| 323 | + FormatInfo info = processor.process(destPath, null, |
| 324 | + templateUuid); |
| 325 | + |
| 326 | + TemplateLocation loc = new TemplateLocation(_storage, destPath); |
| 327 | + loc.create(1, true, templateName); |
| 328 | + loc.addFormat(info); |
| 329 | + loc.save(); |
| 330 | + |
| 331 | + TemplateObjectTO newTemplate = new TemplateObjectTO(); |
| 332 | + newTemplate.setPath(destData.getPath() + File.separator + templateUuid); |
| 333 | + return new CopyCmdAnswer(newTemplate); |
| 334 | + } catch (ConfigurationException e) { |
| 335 | + s_logger.debug("Failed to create template from snapshot: " + e.toString()); |
| 336 | + errMsg = e.toString(); |
| 337 | + } catch (InternalErrorException e) { |
| 338 | + s_logger.debug("Failed to create template from snapshot: " + e.toString()); |
| 339 | + errMsg = e.toString(); |
| 340 | + } catch (IOException e) { |
| 341 | + s_logger.debug("Failed to create template from snapshot: " + e.toString()); |
| 342 | + errMsg = e.toString(); |
| 343 | + } |
285 | 344 |
|
286 | | - DataTO destData, NfsTO destImageStore) { |
287 | | - return Answer.createUnsupportedCommandAnswer(cmd); |
| 345 | + return new CopyCmdAnswer(errMsg); |
288 | 346 | } |
| 347 | + |
| 348 | + protected Answer copySnapshotToTemplateFromNfsToNfs(CopyCommand cmd, SnapshotObjectTO srcData, NfsTO srcDataStore, TemplateObjectTO destData, NfsTO destDataStore) { |
| 349 | + |
| 350 | + if (srcData.getHypervisorType() == HypervisorType.XenServer) { |
| 351 | + return copySnapshotToTemplateFromNfsToNfsXenserver(cmd, srcData, srcDataStore, destData, destDataStore); |
| 352 | + } |
289 | 353 |
|
290 | | - protected Answer execute(CopyCommand cmd) { |
| 354 | + return new CopyCmdAnswer(""); |
| 355 | + } |
| 356 | + |
| 357 | + protected Answer createTemplateFromSnapshot(CopyCommand cmd) { |
291 | 358 | DataTO srcData = cmd.getSrcTO(); |
292 | 359 | DataTO destData = cmd.getDestTO(); |
293 | 360 | DataStoreTO srcDataStore = srcData.getDataStore(); |
294 | 361 | DataStoreTO destDataStore = destData.getDataStore(); |
295 | | - |
296 | | - if (srcDataStore.getRole() == DataStoreRole.Image && destDataStore.getRole() == DataStoreRole.ImageCache) { |
297 | | - |
298 | | - if (!(destDataStore instanceof NfsTO)) { |
299 | | - s_logger.debug("only support nfs as cache storage"); |
| 362 | + if (srcDataStore.getRole() == DataStoreRole.Image || srcDataStore.getRole() == DataStoreRole.ImageCache) { |
| 363 | + if (!(srcDataStore instanceof NfsTO)) { |
| 364 | + s_logger.debug("only support nfs storage as src, when create template from snapshot"); |
300 | 365 | return Answer.createUnsupportedCommandAnswer(cmd); |
301 | 366 | } |
302 | | - |
303 | | - if (srcDataStore instanceof S3TO) { |
304 | | - return copyFromS3ToNfs(cmd, srcData, (S3TO) srcDataStore, destData, (NfsTO) destDataStore); |
305 | | - } else if (srcDataStore instanceof SwiftTO) { |
306 | | - return copyFromSwiftToNfs(cmd, srcData, (SwiftTO) srcDataStore, destData, (NfsTO) destDataStore); |
307 | | - } else { |
308 | | - return Answer.createUnsupportedCommandAnswer(cmd); |
| 367 | + |
| 368 | + if (destDataStore instanceof NfsTO){ |
| 369 | + return copySnapshotToTemplateFromNfsToNfs(cmd, (SnapshotObjectTO)srcData, (NfsTO)srcDataStore, (TemplateObjectTO)destData, (NfsTO)destDataStore); |
309 | 370 | } |
310 | 371 |
|
311 | 372 | } |
| 373 | + return new CopyCmdAnswer(""); |
| 374 | + } |
| 375 | + |
| 376 | + protected Answer execute(CopyCommand cmd) { |
| 377 | + DataTO srcData = cmd.getSrcTO(); |
| 378 | + DataTO destData = cmd.getDestTO(); |
| 379 | + DataStoreTO srcDataStore = srcData.getDataStore(); |
| 380 | + DataStoreTO destDataStore = destData.getDataStore(); |
| 381 | + |
| 382 | + if (srcData.getObjectType() == DataObjectType.SNAPSHOT && destData.getObjectType() == DataObjectType.TEMPLATE) { |
| 383 | + return createTemplateFromSnapshot(cmd); |
| 384 | + } |
| 385 | + |
| 386 | + |
312 | 387 | return Answer.createUnsupportedCommandAnswer(cmd); |
313 | 388 | } |
314 | 389 |
|
@@ -1652,6 +1727,11 @@ public boolean configure(String name, Map<String, Object> params) throws Configu |
1652 | 1727 | if (_configIpFirewallScr != null) { |
1653 | 1728 | s_logger.info("_configIpFirewallScr found in " + _configIpFirewallScr); |
1654 | 1729 | } |
| 1730 | + |
| 1731 | + createTemplateFromSnapshotXenScript = Script.findScript(getDefaultScriptsDir(), "create_privatetemplate_from_snapshot_xen.sh"); |
| 1732 | + if (createTemplateFromSnapshotXenScript == null) { |
| 1733 | + throw new ConfigurationException("create_privatetemplate_from_snapshot_xen.sh not found in " + getDefaultScriptsDir()); |
| 1734 | + } |
1655 | 1735 |
|
1656 | 1736 | _role = (String) params.get("role"); |
1657 | 1737 | if (_role == null) |
|
0 commit comments