You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by li...@apache.org on 2014/05/19 11:47:41 UTC
git commit: updated refs/heads/multiple-disk-ova to fa0897f
Repository: cloudstack
Updated Branches:
refs/heads/multiple-disk-ova 3532ffe5a -> fa0897f90
CLOUDSTACK-4757. More updates to Datadisk template creation - update ROOT disk OVA once all the datadisks have been created
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/fa0897f9
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/fa0897f9
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/fa0897f9
Branch: refs/heads/multiple-disk-ova
Commit: fa0897f902dbb941bb18a0bf63fe1b182f535c86
Parents: 3532ffe
Author: Likitha Shetty <li...@citrix.com>
Authored: Fri May 16 11:32:10 2014 +0530
Committer: Likitha Shetty <li...@citrix.com>
Committed: Mon May 19 15:06:45 2014 +0530
----------------------------------------------------------------------
api/src/com/cloud/agent/api/to/DatadiskTO.java | 60 +++++++++
.../cloud/agent/api/to/DatadiskTemplateTO.java | 74 -----------
.../storage/CreateDatadiskTemplateCommand.java | 8 +-
.../agent/api/storage/GetDatadisksAnswer.java | 8 +-
.../subsystem/api/storage/TemplateService.java | 7 +-
.../image/datastore/ImageStoreEntity.java | 6 +-
.../storage/image/TemplateServiceImpl.java | 123 ++++++++++++++++---
.../storage/image/store/ImageStoreImpl.java | 9 +-
.../storage/image/BaseImageStoreDriverImpl.java | 12 +-
.../storage/image/ImageStoreDriver.java | 6 +-
.../manager/VmwareStorageManagerImpl.java | 76 +++++++-----
.../template/HypervisorTemplateAdapter.java | 63 ----------
server/src/com/cloud/vm/UserVmManagerImpl.java | 16 ++-
13 files changed, 249 insertions(+), 219 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa0897f9/api/src/com/cloud/agent/api/to/DatadiskTO.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/agent/api/to/DatadiskTO.java b/api/src/com/cloud/agent/api/to/DatadiskTO.java
new file mode 100644
index 0000000..514ca98
--- /dev/null
+++ b/api/src/com/cloud/agent/api/to/DatadiskTO.java
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package com.cloud.agent.api.to;
+
+public class DatadiskTO {
+ private String path;
+ private long virtualSize;
+ private long fileSize;
+ boolean bootable;
+
+ public DatadiskTO() {
+ }
+
+ public DatadiskTO(String path, long virtualSize, long fileSize, boolean bootable) {
+ this.path = path;
+ this.virtualSize = virtualSize;
+ this.fileSize = fileSize;
+ this.bootable = bootable;
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ public void setPath(String path) {
+ this.path = path;
+ }
+
+ public Long getVirtualSize() {
+ return virtualSize;
+ }
+
+ public void setVirtualSize(Long virtualSize) {
+ this.virtualSize = virtualSize;
+ }
+
+ public Long getFileSize() {
+ return fileSize;
+ }
+
+ public boolean isBootable() {
+ return bootable;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa0897f9/api/src/com/cloud/agent/api/to/DatadiskTemplateTO.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/agent/api/to/DatadiskTemplateTO.java b/api/src/com/cloud/agent/api/to/DatadiskTemplateTO.java
deleted file mode 100644
index 34d7237..0000000
--- a/api/src/com/cloud/agent/api/to/DatadiskTemplateTO.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package com.cloud.agent.api.to;
-
-public class DatadiskTemplateTO {
- private long id;
- private String uniqueName;
- private String path;
- private Long virtualSize;
- private Long fileSize;
-
- public DatadiskTemplateTO() {
- }
-
- public DatadiskTemplateTO(long id, String uniqueName, String path, Long virtualSize, Long fileSize) {
- this.id = id;
- this.uniqueName = uniqueName;
- this.path = path;
- this.virtualSize = virtualSize;
- this.fileSize = fileSize;
- }
-
- public long getId() {
- return id;
- }
-
- public void setId(long id) {
- this.id = id;
- }
-
- public String getUniqueName() {
- return uniqueName;
- }
-
- public void setUniqueName(String uniqueName) {
- this.uniqueName = uniqueName;
- }
-
- public String getPath() {
- return path;
- }
-
- public void setPath(String path) {
- this.path = path;
- }
-
- public Long getVirtualSize() {
- return virtualSize;
- }
-
- public void setVirtualSize(Long virtualSize) {
- this.virtualSize = virtualSize;
- }
-
- public Long getFileSize() {
- return fileSize;
- }
-}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa0897f9/core/src/com/cloud/agent/api/storage/CreateDatadiskTemplateCommand.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/storage/CreateDatadiskTemplateCommand.java b/core/src/com/cloud/agent/api/storage/CreateDatadiskTemplateCommand.java
index bd3843b..548cc45 100644
--- a/core/src/com/cloud/agent/api/storage/CreateDatadiskTemplateCommand.java
+++ b/core/src/com/cloud/agent/api/storage/CreateDatadiskTemplateCommand.java
@@ -23,12 +23,14 @@ public final class CreateDatadiskTemplateCommand extends Command {
private DataTO dataDiskTemplate;
private String path;
private long fileSize;
+ private boolean bootable;
- public CreateDatadiskTemplateCommand(DataTO dataDiskTemplate, String path, long fileSize) {
+ public CreateDatadiskTemplateCommand(DataTO dataDiskTemplate, String path, long fileSize, boolean bootable) {
super();
this.dataDiskTemplate = dataDiskTemplate;
this.path = path;
this.fileSize = fileSize;
+ this.bootable = bootable;
}
protected CreateDatadiskTemplateCommand() {
@@ -51,4 +53,8 @@ public final class CreateDatadiskTemplateCommand extends Command {
public long getFileSize() {
return fileSize;
}
+
+ public boolean getBootable() {
+ return bootable;
+ }
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa0897f9/core/src/com/cloud/agent/api/storage/GetDatadisksAnswer.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/storage/GetDatadisksAnswer.java b/core/src/com/cloud/agent/api/storage/GetDatadisksAnswer.java
index ffcf26f..5892217 100644
--- a/core/src/com/cloud/agent/api/storage/GetDatadisksAnswer.java
+++ b/core/src/com/cloud/agent/api/storage/GetDatadisksAnswer.java
@@ -20,17 +20,17 @@ import java.util.ArrayList;
import java.util.List;
import com.cloud.agent.api.Answer;
-import com.cloud.utils.Ternary;
+import com.cloud.agent.api.to.DatadiskTO;
public class GetDatadisksAnswer extends Answer {
- List<Ternary<String, Long, Long>> dataDiskDetails = new ArrayList<Ternary<String, Long, Long>>();
+ List<DatadiskTO> dataDiskDetails = new ArrayList<DatadiskTO>();
- public GetDatadisksAnswer(List<Ternary<String, Long, Long>> dataDiskDetails) {
+ public GetDatadisksAnswer(List<DatadiskTO> dataDiskDetails) {
super(null);
this.dataDiskDetails = dataDiskDetails;
}
- public List<Ternary<String, Long, Long>> getDataDiskDetails() {
+ public List<DatadiskTO> getDataDiskDetails() {
return dataDiskDetails;
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa0897f9/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java
index ff045bc..b416e9d 100644
--- a/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java
+++ b/engine/api/src/org/apache/cloudstack/engine/subsystem/api/storage/TemplateService.java
@@ -18,15 +18,12 @@
*/
package org.apache.cloudstack.engine.subsystem.api.storage;
-import java.util.List;
-
import org.apache.cloudstack.framework.async.AsyncCallFuture;
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
import org.apache.cloudstack.storage.command.CommandResult;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.storage.StoragePool;
-import com.cloud.utils.Ternary;
public interface TemplateService {
@@ -69,7 +66,5 @@ public interface TemplateService {
void associateCrosszoneTemplatesToZone(long dcId);
- List<Ternary<String, Long, Long>> getDatadiskTemplates(TemplateInfo template);
-
- AsyncCallFuture<TemplateApiResult> createDatadiskTemplateAsync(TemplateInfo parentTemplate, TemplateInfo dataDiskTemplate, String path, long fileSize);
+ AsyncCallFuture<TemplateApiResult> createDatadiskTemplateAsync(TemplateInfo parentTemplate, TemplateInfo dataDiskTemplate, String path, long fileSize, boolean bootable);
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa0897f9/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java
----------------------------------------------------------------------
diff --git a/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java b/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java
index be419b4..223fc4d 100644
--- a/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java
+++ b/engine/api/src/org/apache/cloudstack/storage/image/datastore/ImageStoreEntity.java
@@ -29,9 +29,9 @@ import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
+import com.cloud.agent.api.to.DatadiskTO;
import com.cloud.storage.ImageStore;
import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.utils.Ternary;
public interface ImageStoreEntity extends DataStore, ImageStore {
TemplateInfo getTemplate(long templateId);
@@ -48,7 +48,7 @@ public interface ImageStoreEntity extends DataStore, ImageStore {
String createEntityExtractUrl(String installPath, ImageFormat format, DataObject dataObject); // get the entity download URL
- List<Ternary<String, Long, Long>> getDatadiskTemplates(DataObject obj);
+ List<DatadiskTO> getDatadiskTemplates(DataObject obj);
- Void createDataDiskTemplateAsync(TemplateInfo dataDiskTemplate, String path, long fileSize, AsyncCompletionCallback<CreateCmdResult> callback);
+ Void createDataDiskTemplateAsync(TemplateInfo dataDiskTemplate, String path, long fileSize, boolean bootable, AsyncCompletionCallback<CreateCmdResult> callback);
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa0897f9/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java
index ffdfcba..c539dab 100644
--- a/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java
+++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/TemplateServiceImpl.java
@@ -67,14 +67,17 @@ import org.apache.cloudstack.storage.to.TemplateObjectTO;
import com.cloud.agent.api.Answer;
import com.cloud.agent.api.storage.ListTemplateAnswer;
import com.cloud.agent.api.storage.ListTemplateCommand;
+import com.cloud.agent.api.to.DatadiskTO;
import com.cloud.alert.AlertManager;
import com.cloud.configuration.Config;
+import com.cloud.configuration.Resource.ResourceType;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.dao.ClusterDao;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.storage.DataStoreRole;
+import com.cloud.storage.ScopeType;
import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.Storage.TemplateType;
import com.cloud.storage.StoragePool;
@@ -91,9 +94,11 @@ import com.cloud.template.TemplateManager;
import com.cloud.user.Account;
import com.cloud.user.AccountManager;
import com.cloud.user.ResourceLimitService;
-import com.cloud.utils.Ternary;
import com.cloud.utils.UriUtils;
import com.cloud.utils.db.GlobalLock;
+import com.cloud.utils.db.Transaction;
+import com.cloud.utils.db.TransactionCallbackNoReturn;
+import com.cloud.utils.db.TransactionStatus;
import com.cloud.utils.exception.CloudRuntimeException;
@Component
@@ -581,6 +586,18 @@ public class TemplateServiceImpl implements TemplateService {
return null;
}
+ // Check if OVA contains additional data disks. If yes, create Datadisk templates for each of the additional datadisk present in the OVA
+ if (template.getFormat().equals(ImageFormat.OVA)) {
+ if(!createDataDiskTemplates(template)) {
+ template.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
+ result.setResult(callbackResult.getResult());
+ if (parentCallback != null) {
+ parentCallback.complete(result);
+ }
+ return null;
+ }
+ }
+
try {
template.processEvent(ObjectInDataStoreStateMachine.Event.OperationSuccessed);
} catch (Exception e) {
@@ -597,6 +614,81 @@ public class TemplateServiceImpl implements TemplateService {
return null;
}
+ protected boolean createDataDiskTemplates(TemplateInfo parentTemplate) {
+ TemplateApiResult result = null;
+ // Get Datadisk template (if any) for OVA
+ List<DatadiskTO> dataDiskTemplates = new ArrayList<DatadiskTO>();
+ ImageStoreEntity tmpltStore = (ImageStoreEntity)parentTemplate.getDataStore();
+ dataDiskTemplates = tmpltStore.getDatadiskTemplates(parentTemplate);
+ s_logger.error("Found " + dataDiskTemplates.size() + " Datadisk template(s) for template: " + parentTemplate.getId());
+ int diskCount = 1;
+ VMTemplateVO template = _templateDao.findById(parentTemplate.getId());
+ DataStore imageStore = parentTemplate.getDataStore();
+ for (DatadiskTO dataDiskTemplate : dataDiskTemplates) {
+ if (dataDiskTemplate.isBootable())
+ continue;
+ // Make an entry in vm_template table
+ final long templateId = _templateDao.getNextInSequence(Long.class, "id");
+ VMTemplateVO templateVO = new VMTemplateVO(templateId, template.getName() + "-DataDiskTemplate-" + diskCount, template.getFormat(), false, false, false,
+ TemplateType.DATADISK, template.getUrl(), template.requiresHvm(), template.getBits(), template.getAccountId(), null,
+ template.getDisplayText() + "-DataDiskTemplate", false, 0, false, template.getHypervisorType(), null, null, false, false);
+ templateVO.setParentTemplateId(template.getId());
+ templateVO.setSize(dataDiskTemplate.getVirtualSize());
+ templateVO = _templateDao.persist(templateVO);
+ // Make sync call to create Datadisk templates in image store
+ TemplateInfo dataDiskTemplateInfo = imageFactory.getTemplate(templateVO.getId(), imageStore);
+ AsyncCallFuture<TemplateApiResult> future = createDatadiskTemplateAsync(parentTemplate, dataDiskTemplateInfo, dataDiskTemplate.getPath(),
+ dataDiskTemplate.getFileSize(), dataDiskTemplate.isBootable());
+ try {
+ result = future.get();
+ if (result.isSuccess()) {
+ // Make an entry in template_zone_ref table
+ if (imageStore.getScope().getScopeType() == ScopeType.REGION) {
+ associateTemplateToZone(templateId, null);
+ } else if (imageStore.getScope().getScopeType() == ScopeType.ZONE) {
+ Long zoneId = ((ImageStoreEntity)imageStore).getDataCenterId();
+ VMTemplateZoneVO templateZone = new VMTemplateZoneVO(zoneId, templateId, new Date());
+ _vmTemplateZoneDao.persist(templateZone);
+ }
+ _resourceLimitMgr.incrementResourceCount(template.getAccountId(), ResourceType.secondary_storage, templateVO.getSize());
+ } else {
+ // Cleanup Datadisk template enries in case of failure
+ Transaction.execute(new TransactionCallbackNoReturn() {
+ @Override
+ public void doInTransactionWithoutResult(TransactionStatus status) {
+ _vmTemplateStoreDao.deletePrimaryRecordsForTemplate(templateId);
+ _vmTemplateZoneDao.deletePrimaryRecordsForTemplate(templateId);
+ _templateDao.expunge(templateId);
+ }
+ });
+ // Don't create the remaining Datadisk templates if creation of any of the Datadisk template failed
+ s_logger.error("Creation of Datadisk: " + templateVO.getId() + " failed: " + result.getResult());
+ return false;
+ }
+ } catch (Exception e) {
+ s_logger.error("Creation of Datadisk: " + templateVO.getId() + " failed: " + result.getResult());
+ return false;
+ }
+ diskCount++;
+ }
+ // Create disk template for the bootable parent template
+ for (DatadiskTO dataDiskTemplate : dataDiskTemplates) {
+ if (dataDiskTemplate.isBootable()) {
+ TemplateInfo templateInfo = imageFactory.getTemplate(template.getId(), imageStore);
+ AsyncCallFuture<TemplateApiResult> templateFuture = createDatadiskTemplateAsync(parentTemplate, templateInfo, dataDiskTemplate.getPath(),
+ dataDiskTemplate.getFileSize(), dataDiskTemplate.isBootable());
+ try {
+ result = templateFuture.get();
+ return result.isSuccess();
+ } catch (Exception e) {
+ s_logger.error("Creation of template: " + template.getId() + " failed: " + result.getResult());
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
@Override
public AsyncCallFuture<TemplateApiResult> deleteTemplateAsync(TemplateInfo template) {
TemplateObject to = (TemplateObject)template;
@@ -891,14 +983,6 @@ public class TemplateServiceImpl implements TemplateService {
}
}
- @Override
- public List<Ternary<String, Long, Long>> getDatadiskTemplates(TemplateInfo template) {
- List<Ternary<String, Long, Long>> dataDiskDetails = new ArrayList<Ternary<String, Long, Long>>();
- ImageStoreEntity tmpltStore = (ImageStoreEntity)template.getDataStore();
- dataDiskDetails = tmpltStore.getDatadiskTemplates(template);
- return dataDiskDetails;
- }
-
private class CreateDataDiskTemplateContext<T> extends AsyncRpcContext<T> {
private final DataObject dataDiskTemplate;
private final AsyncCallFuture<TemplateApiResult> future;
@@ -915,18 +999,23 @@ public class TemplateServiceImpl implements TemplateService {
}
@Override
- public AsyncCallFuture<TemplateApiResult> createDatadiskTemplateAsync(TemplateInfo parentTemplate, TemplateInfo dataDiskTemplate, String path, long fileSize) {
+ public AsyncCallFuture<TemplateApiResult> createDatadiskTemplateAsync(TemplateInfo parentTemplate, TemplateInfo dataDiskTemplate, String path, long fileSize, boolean bootable) {
AsyncCallFuture<TemplateApiResult> future = new AsyncCallFuture<TemplateApiResult>();
// Make an entry for Datadisk template in template_store_ref table
DataStore store = parentTemplate.getDataStore();
- TemplateObject dataDiskTemplateOnStore = (TemplateObject)store.create(dataDiskTemplate);
- dataDiskTemplateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.CreateOnlyRequested);
+ TemplateObject dataDiskTemplateOnStore;
+ if (!bootable) {
+ dataDiskTemplateOnStore = (TemplateObject)store.create(dataDiskTemplate);
+ dataDiskTemplateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.CreateOnlyRequested);
+ } else {
+ dataDiskTemplateOnStore = (TemplateObject) imageFactory.getTemplate(parentTemplate, store);
+ }
try {
CreateDataDiskTemplateContext<TemplateApiResult> context = new CreateDataDiskTemplateContext<TemplateApiResult>(null, dataDiskTemplateOnStore, future);
AsyncCallbackDispatcher<TemplateServiceImpl, CreateCmdResult> caller = AsyncCallbackDispatcher.create(this);
- caller.setCallback(caller.getTarget().createDataDiskTemplateCallback(null, null)).setContext(context);
+ caller.setCallback(caller.getTarget().createDatadiskTemplateCallback(null, null)).setContext(context);
ImageStoreEntity tmpltStore = (ImageStoreEntity)parentTemplate.getDataStore();
- tmpltStore.createDataDiskTemplateAsync(dataDiskTemplate, path, fileSize, caller);
+ tmpltStore.createDataDiskTemplateAsync(dataDiskTemplate, path, fileSize, bootable, caller);
} catch (CloudRuntimeException ex) {
dataDiskTemplateOnStore.processEvent(ObjectInDataStoreStateMachine.Event.OperationFailed);
TemplateApiResult result = new TemplateApiResult(dataDiskTemplate);
@@ -938,7 +1027,7 @@ public class TemplateServiceImpl implements TemplateService {
return future;
}
- protected Void createDataDiskTemplateCallback(AsyncCallbackDispatcher<TemplateServiceImpl, CreateCmdResult> callback, CreateDataDiskTemplateContext<TemplateApiResult> context) {
+ protected Void createDatadiskTemplateCallback(AsyncCallbackDispatcher<TemplateServiceImpl, CreateCmdResult> callback, CreateDataDiskTemplateContext<TemplateApiResult> context) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Performing create datadisk template cross callback after completion");
}
@@ -954,10 +1043,10 @@ public class TemplateServiceImpl implements TemplateService {
dataDiskTemplateResult.setResult(result.getResult());
}
} catch (Exception e) {
- s_logger.debug("Failed to process copy template cross zones callback", e);
+ s_logger.debug("Failed to process create datadisk template callback", e);
dataDiskTemplateResult.setResult(e.toString());
}
future.complete(dataDiskTemplateResult);
return null;
}
-}
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa0897f9/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java
index 0a3b7e8..97f09d0 100644
--- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java
+++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/ImageStoreImpl.java
@@ -45,12 +45,12 @@ import org.apache.cloudstack.storage.image.ImageStoreDriver;
import org.apache.cloudstack.storage.image.datastore.ImageStoreEntity;
import org.apache.cloudstack.storage.to.ImageStoreTO;
+import com.cloud.agent.api.to.DatadiskTO;
import com.cloud.agent.api.to.DataStoreTO;
import com.cloud.capacity.dao.CapacityDao;
import com.cloud.storage.DataStoreRole;
import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.dao.VMTemplateDao;
-import com.cloud.utils.Ternary;
import com.cloud.utils.component.ComponentContext;
public class ImageStoreImpl implements ImageStoreEntity {
@@ -208,13 +208,12 @@ public class ImageStoreImpl implements ImageStoreEntity {
}
@Override
- public List<Ternary<String, Long, Long>> getDatadiskTemplates(DataObject obj) {
+ public List<DatadiskTO> getDatadiskTemplates(DataObject obj) {
return driver.getDatadiskTemplates(obj);
}
@Override
- public Void createDataDiskTemplateAsync(TemplateInfo dataDiskTemplate, String path, long fileSize, AsyncCompletionCallback<CreateCmdResult> callback) {
- return driver.createDataDiskTemplateAsync(dataDiskTemplate, path, fileSize, callback);
-
+ public Void createDataDiskTemplateAsync(TemplateInfo dataDiskTemplate, String path, long fileSize, boolean bootable, AsyncCompletionCallback<CreateCmdResult> callback) {
+ return driver.createDataDiskTemplateAsync(dataDiskTemplate, path, bootable, fileSize, callback);
}
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa0897f9/engine/storage/src/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java
index 94366ef..b170c75 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/image/BaseImageStoreDriverImpl.java
@@ -54,6 +54,7 @@ import com.cloud.agent.api.storage.DownloadAnswer;
import com.cloud.agent.api.storage.GetDatadisksAnswer;
import com.cloud.agent.api.storage.GetDatadisksCommand;
import com.cloud.agent.api.storage.Proxy;
+import com.cloud.agent.api.to.DatadiskTO;
import com.cloud.agent.api.to.DataObjectType;
import com.cloud.agent.api.to.DataTO;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
@@ -66,7 +67,6 @@ import com.cloud.storage.dao.VolumeDao;
import com.cloud.storage.download.DownloadMonitor;
import com.cloud.user.ResourceLimitService;
import com.cloud.user.dao.AccountDao;
-import com.cloud.utils.Ternary;
public abstract class BaseImageStoreDriverImpl implements ImageStoreDriver {
private static final Logger s_logger = Logger.getLogger(BaseImageStoreDriverImpl.class);
@@ -293,8 +293,8 @@ public abstract class BaseImageStoreDriverImpl implements ImageStoreDriver {
}
@Override
- public List<Ternary<String, Long, Long>> getDatadiskTemplates(DataObject obj) {
- List<Ternary<String, Long, Long>> dataDiskDetails = new ArrayList<Ternary<String, Long, Long>>();
+ public List<DatadiskTO> getDatadiskTemplates(DataObject obj) {
+ List<DatadiskTO> dataDiskDetails = new ArrayList<DatadiskTO>();
if (s_logger.isDebugEnabled()) {
s_logger.debug("Get the data disks present in the OVA template");
}
@@ -311,20 +311,20 @@ public abstract class BaseImageStoreDriverImpl implements ImageStoreDriver {
}
if (answer != null && answer.getResult()) {
GetDatadisksAnswer getDatadisksAnswer = (GetDatadisksAnswer)answer;
- dataDiskDetails = getDatadisksAnswer.getDataDiskDetails(); // Details - Disk path, virtual size
+ dataDiskDetails = getDatadisksAnswer.getDataDiskDetails(); // Details - Disk path, virtual size, bootable
}
return dataDiskDetails;
}
@Override
- public Void createDataDiskTemplateAsync(TemplateInfo dataDiskTemplate, String path, long fileSize,
+ public Void createDataDiskTemplateAsync(TemplateInfo dataDiskTemplate, String path, boolean bootable, long fileSize,
AsyncCompletionCallback<CreateCmdResult> callback) {
Answer answer = null;
String errMsg = null;
if (s_logger.isDebugEnabled()) {
s_logger.debug("Create Datadisk template: " + dataDiskTemplate.getId());
}
- CreateDatadiskTemplateCommand cmd = new CreateDatadiskTemplateCommand(dataDiskTemplate.getTO(), path, fileSize);
+ CreateDatadiskTemplateCommand cmd = new CreateDatadiskTemplateCommand(dataDiskTemplate.getTO(), path, fileSize, bootable);
EndPoint ep = _defaultEpSelector.selectHypervisorHostByType(dataDiskTemplate.getDataStore().getScope(), HypervisorType.VMware);
if (ep == null) {
errMsg = "No remote endpoint to send command, check if host or ssvm is down?";
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa0897f9/engine/storage/src/org/apache/cloudstack/storage/image/ImageStoreDriver.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/ImageStoreDriver.java b/engine/storage/src/org/apache/cloudstack/storage/image/ImageStoreDriver.java
index e4e9451..a262c9b 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/image/ImageStoreDriver.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/image/ImageStoreDriver.java
@@ -27,13 +27,13 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreDriver;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
+import com.cloud.agent.api.to.DatadiskTO;
import com.cloud.storage.Storage.ImageFormat;
-import com.cloud.utils.Ternary;
public interface ImageStoreDriver extends DataStoreDriver {
String createEntityExtractUrl(DataStore store, String installPath, ImageFormat format, DataObject dataObject);
- List<Ternary<String, Long, Long>> getDatadiskTemplates(DataObject obj);
+ List<DatadiskTO> getDatadiskTemplates(DataObject obj);
- Void createDataDiskTemplateAsync(TemplateInfo dataDiskTemplate, String path, long fileSize, AsyncCompletionCallback<CreateCmdResult> callback);
+ Void createDataDiskTemplateAsync(TemplateInfo dataDiskTemplate, String path, boolean bootable, long fileSize, AsyncCompletionCallback<CreateCmdResult> callback);
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa0897f9/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
index 9a3ce40..b1001f8 100644
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/manager/VmwareStorageManagerImpl.java
@@ -68,6 +68,7 @@ import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
import com.cloud.agent.api.to.DataObjectType;
import com.cloud.agent.api.to.DataStoreTO;
import com.cloud.agent.api.to.DataTO;
+import com.cloud.agent.api.to.DatadiskTO;
import com.cloud.agent.api.to.NfsTO;
import com.cloud.agent.api.to.StorageFilerTO;
import com.cloud.hypervisor.vmware.mo.CustomFieldConstants;
@@ -550,7 +551,7 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
@Override
public Answer execute(VmwareHostService hostService, GetDatadisksCommand cmd) {
- List<Ternary<String, Long, Long>> datDiskDetails = new ArrayList<Ternary<String, Long, Long>>();
+ List<DatadiskTO> disks = new ArrayList<DatadiskTO>();
DataTO srcData = cmd.getData();
TemplateObjectTO template = (TemplateObjectTO)srcData;
DataStoreTO srcStore = srcData.getDataStore();
@@ -603,22 +604,19 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
s_logger.debug("Reading OVF " + ovfFilePath + " to retrive the number of disks present in OVA");
List<Pair<String, Boolean>> ovfVolumeDetails = HypervisorHostHelper.readOVF(hyperHost, ovfFilePath, datastoreMo);
- // Get the virtual size of data disk
+ // Get OVA disk details
for (Pair<String, Boolean> ovfVolumeDetail : ovfVolumeDetails) {
- if (ovfVolumeDetail.second()) { // ROOT disk
- continue;
- }
String dataDiskPath = ovfVolumeDetail.first();
String diskName = dataDiskPath.substring((dataDiskPath.lastIndexOf(File.separator)) + 1);
Pair<Long, Long> diskDetails = new OVAProcessor().getDiskDetails(ovfFilePath, diskName);
- datDiskDetails.add(new Ternary<String, Long, Long>(dataDiskPath, diskDetails.first(), diskDetails.second()));
+ disks.add(new DatadiskTO(dataDiskPath, diskDetails.first(), diskDetails.second(), ovfVolumeDetail.second()));
}
} catch (Exception e) {
String msg = "Get Datadisk Template Count failed due to " + e.getMessage();
s_logger.error(msg);
return new GetDatadisksAnswer(msg);
}
- return new GetDatadisksAnswer(datDiskDetails);
+ return new GetDatadisksAnswer(disks);
}
@Override
@@ -653,36 +651,50 @@ public class VmwareStorageManagerImpl implements VmwareStorageManager {
long physicalSize = new File(dataDiskPath).length();
String dataDiskTemplateFolderPath = getTemplateRelativeDirInSecStorage(dataDiskTemplate.getAccountId(), dataDiskTemplate.getId());
String dataDiskTemplateFolderFullPath = secondaryMountPoint + "/" + dataDiskTemplateFolderPath;
+ String ovfName = diskName.substring(0, diskName.lastIndexOf("-"));
+ String datastorePath = String.format("[%s] %s", datastoreMo.getName(), dataDiskTemplateFolderPath);
- // Create folder to hold datadisk template
- synchronized (dataDiskTemplateFolderPath.intern()) {
- Script command = new Script(false, "mkdir", _timeout, s_logger);
- command.add("-p");
- command.add(dataDiskTemplateFolderFullPath);
- String result = command.execute();
- if (result != null) {
- String msg = "Unable to prepare template directory: " + dataDiskTemplateFolderPath + ", storage: " + secondaryStorageUrl + ", error msg: " + result;
- s_logger.error(msg);
- throw new Exception(msg);
+ if (!cmd.getBootable()) {
+ // Create folder to hold datadisk template
+ synchronized (dataDiskTemplateFolderPath.intern()) {
+ Script command = new Script(false, "mkdir", _timeout, s_logger);
+ command.add("-p");
+ command.add(dataDiskTemplateFolderFullPath);
+ String result = command.execute();
+ if (result != null) {
+ String msg = "Unable to prepare template directory: " + dataDiskTemplateFolderPath + ", storage: " + secondaryStorageUrl + ", error msg: " + result;
+ s_logger.error(msg);
+ throw new Exception(msg);
+ }
}
- }
-
- // Copy Datadisk VMDK from parent template folder to Datadisk template folder
- synchronized (dataDiskPath.intern()) {
- Script command = new Script(false, "cp", _timeout, s_logger);
- command.add(dataDiskPath);
- command.add(dataDiskTemplateFolderFullPath);
- String result = command.execute();
- if (result != null) {
- String msg = "Unable to copy VMDK from parent template folder to datadisk template folder" + ", error msg: " + result;
- s_logger.error(msg);
- throw new Exception(msg);
+ // Move Datadisk VMDK from parent template folder to Datadisk template folder
+ synchronized (dataDiskPath.intern()) {
+ Script command = new Script(false, "mv", _timeout, s_logger);
+ command.add(dataDiskPath);
+ command.add(dataDiskTemplateFolderFullPath);
+ String result = command.execute();
+ if (result != null) {
+ String msg = "Unable to copy VMDK from parent template folder to datadisk template folder" + ", error msg: " + result;
+ s_logger.error(msg);
+ throw new Exception(msg);
+ }
+ }
+ } else {
+ // Delete original OVA as a new OVA will be created for the root disk template
+ String rootDiskTemplatePath = dataDiskTemplate.getPath();
+ String rootDiskTemplateFullPath = secondaryMountPoint + "/" + rootDiskTemplatePath;
+ synchronized (rootDiskTemplateFullPath.intern()) {
+ Script command = new Script(false, "rm", _timeout, s_logger);
+ command.add(rootDiskTemplateFullPath);
+ String result = command.execute();
+ if (result != null) {
+ String msg = "Unable to delete original OVA" + ", error msg: " + result;
+ s_logger.error(msg);
+ throw new Exception(msg);
+ }
}
}
- String ovfName = diskName.substring(0, diskName.lastIndexOf("-"));
- String datastorePath = String.format("[%s] %s", datastoreMo.getName(), dataDiskTemplateFolderPath);
-
// Create OVF for Datadisk
s_logger.debug("Creating OVF file for datadisk " + diskName + " in " + dataDiskTemplateFolderFullPath);
HypervisorHostHelper.createOvfFile(hyperHost, diskName, ovfName, datastorePath, dataDiskTemplateFolderFullPath, virtualSize, fileSize, morDs);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa0897f9/server/src/com/cloud/template/HypervisorTemplateAdapter.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/template/HypervisorTemplateAdapter.java b/server/src/com/cloud/template/HypervisorTemplateAdapter.java
index f984872..8bef4a5 100755
--- a/server/src/com/cloud/template/HypervisorTemplateAdapter.java
+++ b/server/src/com/cloud/template/HypervisorTemplateAdapter.java
@@ -19,7 +19,6 @@ package com.cloud.template;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collections;
-import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -75,13 +74,9 @@ import com.cloud.storage.dao.VMTemplateZoneDao;
import com.cloud.storage.download.DownloadMonitor;
import com.cloud.user.Account;
import com.cloud.utils.Pair;
-import com.cloud.utils.Ternary;
import com.cloud.utils.UriUtils;
import com.cloud.utils.db.DB;
import com.cloud.utils.db.EntityManager;
-import com.cloud.utils.db.Transaction;
-import com.cloud.utils.db.TransactionCallbackNoReturn;
-import com.cloud.utils.db.TransactionStatus;
import com.cloud.utils.exception.CloudRuntimeException;
@Local(value = TemplateAdapter.class)
@@ -301,10 +296,6 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase {
TemplateInfo template = context.template;
if (result.isSuccess()) {
VMTemplateVO tmplt = _tmpltDao.findById(template.getId());
- // Check if OVA contains additional data disks. If yes, create Datadisk templates for each of the additional datadisk present in the OVA
- if (template.getFormat().equals(ImageFormat.OVA)) {
- createDataDiskTemplates(template);
- }
// need to grant permission for public templates
if (tmplt.isPublicTemplate()) {
_messageBus.publish(_name, TemplateManager.MESSAGE_REGISTER_PUBLIC_TEMPLATE_EVENT, PublishScope.LOCAL, tmplt.getId());
@@ -346,60 +337,6 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase {
return null;
}
- private void createDataDiskTemplates(TemplateInfo parentTemplate) {
- TemplateApiResult result = null;
- VMTemplateVO template = _tmpltDao.findById(parentTemplate.getId());
- DataStore imageStore = parentTemplate.getDataStore();
- List<Ternary<String, Long, Long>> dataDiskTemplates = imageService.getDatadiskTemplates(parentTemplate);
- s_logger.error("Found " + dataDiskTemplates.size() + " Datadisk templates for template: " + parentTemplate.getId());
- int diskCount = 1;
- for (Ternary<String, Long, Long> dataDiskTemplate : dataDiskTemplates) {
- // Make an entry in vm_template table
- final long templateId = _templateDao.getNextInSequence(Long.class, "id");
- VMTemplateVO templateVO = new VMTemplateVO(templateId, template.getName() + "-DataDiskTemplate-" + diskCount, template.getFormat(), false, false, false,
- TemplateType.DATADISK, template.getUrl(), template.requiresHvm(), template.getBits(), template.getAccountId(), null,
- template.getDisplayText() + "-DataDiskTemplate", false, 0, false, template.getHypervisorType(), null, null, false, false);
- templateVO.setParentTemplateId(template.getId());
- templateVO.setSize(dataDiskTemplate.second());
- templateVO = _templateDao.persist(templateVO);
- // Make sync call to create Datadisk templates in image store
- TemplateInfo dataDiskTemplateInfo = imageFactory.getTemplate(templateVO.getId(), imageStore);
- AsyncCallFuture<TemplateApiResult> future = imageService.createDatadiskTemplateAsync(parentTemplate, dataDiskTemplateInfo, dataDiskTemplate.first(),
- dataDiskTemplate.third());
- try {
- result = future.get();
- if (result.isSuccess()) {
- // Make an entry in template_zone_ref table
- if (imageStore.getScope().getScopeType() == ScopeType.REGION) {
- imageService.associateTemplateToZone(templateId, null);
- } else if (imageStore.getScope().getScopeType() == ScopeType.ZONE) {
- Long zoneId = ((ImageStoreEntity)imageStore).getDataCenterId();
- VMTemplateZoneVO templateZone = new VMTemplateZoneVO(zoneId, templateId, new Date());
- _tmpltZoneDao.persist(templateZone);
- }
- _resourceLimitMgr.incrementResourceCount(template.getAccountId(), ResourceType.secondary_storage, templateVO.getSize());
- } else {
- // Cleanup Datadisk template enries in case of failure
- Transaction.execute(new TransactionCallbackNoReturn() {
- @Override
- public void doInTransactionWithoutResult(TransactionStatus status) {
- _tmplStoreDao.deletePrimaryRecordsForTemplate(templateId);
- _tmpltZoneDao.deletePrimaryRecordsForTemplate(templateId);
- _tmpltDao.expunge(templateId);
- }
- });
- // Continue to create the remaining Datadisk templates even if creation of 1 Datadisk template failes
- s_logger.error("Creation of Datadisk: " + templateVO.getId() + " failed: " + result.getResult());
- continue;
- }
- } catch (Exception e) {
- s_logger.error("Creation of Datadisk: " + templateVO.getId() + " failed: " + result.getResult());
- continue;
- }
- diskCount++;
- }
- }
-
@Override
@DB
public boolean delete(TemplateProfile profile) {
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/fa0897f9/server/src/com/cloud/vm/UserVmManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java
index 9a0d2a1..8a719de 100755
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@ -2612,18 +2612,24 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
(dataDiskTemplate.getState().equals(VirtualMachineTemplate.State.Active))) {
throw new InvalidParameterValueException("Invalid template id specified for Datadisk template" + datadiskTemplateToDiskOffering.getKey());
}
+ long dataDiskTemplateId = datadiskTemplateToDiskOffering.getKey();
if (!dataDiskTemplate.getParentTemplateId().equals(template.getId())) {
- throw new InvalidParameterValueException("Invalid Datadisk template. Specified Datadisk template " + datadiskTemplateToDiskOffering.getKey()
+ throw new InvalidParameterValueException("Invalid Datadisk template. Specified Datadisk template " + dataDiskTemplateId
+ " doesn't belong to template " + template.getId());
}
if (dataDiskOffering == null) {
- throw new InvalidParameterValueException("Invalid disk offering id specified" + datadiskTemplateToDiskOffering.getValue());
+ throw new InvalidParameterValueException("Invalid disk offering id " + datadiskTemplateToDiskOffering.getValue().getId() +
+ " specified for datadisk template " + dataDiskTemplateId);
}
- _templateDao.loadDetails(dataDiskTemplate);
if (dataDiskOffering.isCustomized()) {
- throw new InvalidParameterValueException("Invalid disk offering id specified" + datadiskTemplateToDiskOffering.getValue() + ". Custom Disk offerings are not" +
- " supported for Datadisk templates");
+ throw new InvalidParameterValueException("Invalid disk offering id " + dataDiskOffering.getId() + " specified for datadisk template " +
+ dataDiskTemplateId + ". Custom Disk offerings are not supported for Datadisk templates");
+ }
+ if (dataDiskOffering.getDiskSize() < dataDiskTemplate.getSize()) {
+ throw new InvalidParameterValueException("Invalid disk offering id " + dataDiskOffering.getId() + " specified for datadisk template " +
+ dataDiskTemplateId + ". Disk offering size should be greater than or equal to the template size");
}
+ _templateDao.loadDetails(dataDiskTemplate);
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.volume, 1);
_resourceLimitMgr.checkResourceLimit(owner, ResourceType.primary_storage, dataDiskOffering.getDiskSize());
}