You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ko...@apache.org on 2015/01/16 13:34:35 UTC
git commit: updated refs/heads/volume-upload to 053c160
Repository: cloudstack
Updated Branches:
refs/heads/volume-upload 1bf405873 -> 053c160b0
volume upload: management server polling and upload status from agent
MS polling logic to query status for templates that are uploaded
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/053c160b
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/053c160b
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/053c160b
Branch: refs/heads/volume-upload
Commit: 053c160b0fb5ba537d56c6d460998c2231904439
Parents: 1bf4058
Author: Koushik Das <ko...@apache.org>
Authored: Fri Jan 16 18:03:36 2015 +0530
Committer: Koushik Das <ko...@apache.org>
Committed: Fri Jan 16 18:03:36 2015 +0530
----------------------------------------------------------------------
.../cloud/template/VirtualMachineTemplate.java | 38 +++++++-
.../src/com/cloud/storage/VMTemplateVO.java | 3 +
.../com/cloud/storage/dao/VMTemplateDao.java | 4 +-
.../cloud/storage/dao/VMTemplateDaoImpl.java | 72 +++++++++++++++
.../datastore/db/TemplateDataStoreDao.java | 3 +
.../storage/image/store/TemplateObject.java | 20 ++++-
.../storage/image/TemplateEntityImpl.java | 17 ++++
.../image/db/TemplateDataStoreDaoImpl.java | 19 +++-
.../image/db/VolumeDataStoreDaoImpl.java | 4 +-
.../storage/ImageStoreUploadMonitorImpl.java | 92 ++++++++++++++++++++
10 files changed, 264 insertions(+), 8 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/053c160b/api/src/com/cloud/template/VirtualMachineTemplate.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/template/VirtualMachineTemplate.java b/api/src/com/cloud/template/VirtualMachineTemplate.java
index 599212b..39229e5 100755
--- a/api/src/com/cloud/template/VirtualMachineTemplate.java
+++ b/api/src/com/cloud/template/VirtualMachineTemplate.java
@@ -26,10 +26,37 @@ import org.apache.cloudstack.api.InternalIdentity;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.Storage.TemplateType;
+import com.cloud.utils.fsm.StateMachine2;
+import com.cloud.utils.fsm.StateObject;
-public interface VirtualMachineTemplate extends ControlledEntity, Identity, InternalIdentity {
+public interface VirtualMachineTemplate extends ControlledEntity, Identity, InternalIdentity, StateObject<VirtualMachineTemplate.State> {
enum State {
- Active, Inactive;
+ Active,
+ Inactive,
+ NotUploaded,
+ UploadInProgress,
+ UploadError,
+ UploadAbandoned;
+
+ public static StateMachine2<State, Event, VirtualMachineTemplate> getStateMachine() {
+ return s_fsm;
+ }
+
+ private final static StateMachine2<State, Event, VirtualMachineTemplate> s_fsm = new StateMachine2<State, Event, VirtualMachineTemplate>();
+ static {
+ s_fsm.addTransition(new StateMachine2.Transition<State, Event>(NotUploaded, Event.OperationTimeout, UploadAbandoned, null));
+ s_fsm.addTransition(new StateMachine2.Transition<State, Event>(NotUploaded, Event.UploadRequested, UploadInProgress, null));
+ s_fsm.addTransition(new StateMachine2.Transition<State, Event>(UploadInProgress, Event.OperationSucceeded, Active, null));
+ s_fsm.addTransition(new StateMachine2.Transition<State, Event>(UploadInProgress, Event.OperationFailed, UploadError, null));
+ s_fsm.addTransition(new StateMachine2.Transition<State, Event>(UploadInProgress, Event.OperationTimeout, UploadError, null));
+ }
+ }
+
+ enum Event {
+ OperationFailed,
+ OperationSucceeded,
+ UploadRequested,
+ OperationTimeout;
}
public static enum BootloaderType {
@@ -47,6 +74,7 @@ public interface VirtualMachineTemplate extends ControlledEntity, Identity, Inte
all // all templates (only usable by admins)
}
+ @Override
State getState();
boolean isFeatured();
@@ -100,4 +128,10 @@ public interface VirtualMachineTemplate extends ControlledEntity, Identity, Inte
Map getDetails();
boolean isDynamicallyScalable();
+
+ long getUpdatedCount();
+
+ void incrUpdatedCount();
+
+ Date getUpdated();
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/053c160b/engine/schema/src/com/cloud/storage/VMTemplateVO.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/storage/VMTemplateVO.java b/engine/schema/src/com/cloud/storage/VMTemplateVO.java
index d44de22..dd2b35a 100755
--- a/engine/schema/src/com/cloud/storage/VMTemplateVO.java
+++ b/engine/schema/src/com/cloud/storage/VMTemplateVO.java
@@ -582,10 +582,12 @@ public class VMTemplateVO implements VirtualMachineTemplate {
return size;
}
+ @Override
public long getUpdatedCount() {
return updatedCount;
}
+ @Override
public void incrUpdatedCount() {
updatedCount++;
}
@@ -594,6 +596,7 @@ public class VMTemplateVO implements VirtualMachineTemplate {
updatedCount--;
}
+ @Override
public Date getUpdated() {
return updated;
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/053c160b/engine/schema/src/com/cloud/storage/dao/VMTemplateDao.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateDao.java b/engine/schema/src/com/cloud/storage/dao/VMTemplateDao.java
index 2b815d8..a3adffc 100755
--- a/engine/schema/src/com/cloud/storage/dao/VMTemplateDao.java
+++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateDao.java
@@ -21,12 +21,14 @@ import java.util.Map;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.storage.VMTemplateVO;
+import com.cloud.template.VirtualMachineTemplate;
import com.cloud.utils.db.GenericDao;
+import com.cloud.utils.fsm.StateDao;
/*
* Data Access Object for vm_templates table
*/
-public interface VMTemplateDao extends GenericDao<VMTemplateVO, Long> {
+public interface VMTemplateDao extends GenericDao<VMTemplateVO, Long>, StateDao<VirtualMachineTemplate.State, VirtualMachineTemplate.Event, VirtualMachineTemplate> {
public List<VMTemplateVO> listByPublic();
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/053c160b/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java b/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java
index 401a4a2..90196a8 100755
--- a/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java
+++ b/engine/schema/src/com/cloud/storage/dao/VMTemplateDaoImpl.java
@@ -59,6 +59,7 @@ import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.SearchCriteria.Func;
import com.cloud.utils.db.TransactionLegacy;
+import com.cloud.utils.db.UpdateBuilder;
import com.cloud.utils.exception.CloudRuntimeException;
@Component
@@ -104,6 +105,7 @@ public class VMTemplateDaoImpl extends GenericDaoBase<VMTemplateVO, Long> implem
private SearchBuilder<VMTemplateVO> UserIsoSearch;
private GenericSearchBuilder<VMTemplateVO, Long> CountTemplatesByAccount;
// private SearchBuilder<VMTemplateVO> updateStateSearch;
+ private SearchBuilder<VMTemplateVO> AllFieldsSearch;
@Inject
ResourceTagDao _tagsDao;
@@ -393,6 +395,16 @@ public class VMTemplateDaoImpl extends GenericDaoBase<VMTemplateVO, Long> implem
// updateStateSearch.and("updatedCount", updateStateSearch.entity().getUpdatedCount(), Op.EQ);
// updateStateSearch.done();
+ AllFieldsSearch = createSearchBuilder();
+ AllFieldsSearch.and("state", AllFieldsSearch.entity().getState(), SearchCriteria.Op.EQ);
+ AllFieldsSearch.and("accountId", AllFieldsSearch.entity().getAccountId(), SearchCriteria.Op.EQ);
+ AllFieldsSearch.and("id", AllFieldsSearch.entity().getId(), SearchCriteria.Op.EQ);
+ AllFieldsSearch.and("destroyed", AllFieldsSearch.entity().getState(), SearchCriteria.Op.EQ);
+ AllFieldsSearch.and("notDestroyed", AllFieldsSearch.entity().getState(), SearchCriteria.Op.NEQ);
+ AllFieldsSearch.and("updatedCount", AllFieldsSearch.entity().getUpdatedCount(), SearchCriteria.Op.EQ);
+ AllFieldsSearch.and("name", AllFieldsSearch.entity().getName(), SearchCriteria.Op.EQ);
+ AllFieldsSearch.done();
+
return result;
}
@@ -1000,4 +1012,64 @@ public class VMTemplateDaoImpl extends GenericDaoBase<VMTemplateVO, Long> implem
* return templateZonePairList; }
*/
+ @Override
+ public boolean updateState(
+ com.cloud.template.VirtualMachineTemplate.State currentState,
+ com.cloud.template.VirtualMachineTemplate.Event event,
+ com.cloud.template.VirtualMachineTemplate.State nextState,
+ VirtualMachineTemplate vo, Object data) {
+
+ Long oldUpdated = vo.getUpdatedCount();
+ Date oldUpdatedTime = vo.getUpdated();
+
+ SearchCriteria<VMTemplateVO> sc = AllFieldsSearch.create();
+ sc.setParameters("id", vo.getId());
+ sc.setParameters("state", currentState);
+ sc.setParameters("updatedCount", vo.getUpdatedCount());
+
+ vo.incrUpdatedCount();
+
+ UpdateBuilder builder = getUpdateBuilder(vo);
+ builder.set(vo, "state", nextState);
+ builder.set(vo, "updated", new Date());
+
+ int rows = update((VMTemplateVO)vo, sc);
+ if (rows == 0 && s_logger.isDebugEnabled()) {
+ VMTemplateVO dbTemplate = findByIdIncludingRemoved(vo.getId());
+ if (dbTemplate != null) {
+ StringBuilder str = new StringBuilder("Unable to update ").append(vo.toString());
+ str.append(": DB Data={id=")
+ .append(dbTemplate.getId())
+ .append("; state=")
+ .append(dbTemplate.getState())
+ .append("; updatecount=")
+ .append(dbTemplate.getUpdatedCount())
+ .append(";updatedTime=")
+ .append(dbTemplate.getUpdated());
+ str.append(": New Data={id=")
+ .append(vo.getId())
+ .append("; state=")
+ .append(nextState)
+ .append("; event=")
+ .append(event)
+ .append("; updatecount=")
+ .append(vo.getUpdatedCount())
+ .append("; updatedTime=")
+ .append(vo.getUpdated());
+ str.append(": stale Data={id=")
+ .append(vo.getId())
+ .append("; state=")
+ .append(currentState)
+ .append("; event=")
+ .append(event)
+ .append("; updatecount=")
+ .append(oldUpdated)
+ .append("; updatedTime=")
+ .append(oldUpdatedTime);
+ } else {
+ s_logger.debug("Unable to update template: id=" + vo.getId() + ", as no such template exists in the database anymore");
+ }
+ }
+ return rows > 0;
+ }
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/053c160b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java
index 9f8bccd..4da779c 100644
--- a/engine/schema/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java
+++ b/engine/schema/src/org/apache/cloudstack/storage/datastore/db/TemplateDataStoreDao.java
@@ -25,6 +25,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreState
import com.cloud.storage.DataStoreRole;
import com.cloud.storage.VMTemplateStorageResourceAssoc;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
+import com.cloud.template.VirtualMachineTemplate;
import com.cloud.utils.db.GenericDao;
import com.cloud.utils.fsm.StateDao;
@@ -80,4 +81,6 @@ public interface TemplateDataStoreDao extends GenericDao<TemplateDataStoreVO, Lo
void removeByTemplateStore(long templateId, long imageStoreId);
void expireDnldUrlsForZone(Long dcId);
+
+ List<TemplateDataStoreVO> listByTemplateState(VirtualMachineTemplate.State... states);
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/053c160b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java
----------------------------------------------------------------------
diff --git a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java
index e4b04de..197caa7 100644
--- a/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java
+++ b/engine/storage/image/src/org/apache/cloudstack/storage/image/store/TemplateObject.java
@@ -28,7 +28,6 @@ import org.apache.log4j.Logger;
import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine;
-import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
import org.apache.cloudstack.engine.subsystem.api.storage.PrimaryDataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
import org.apache.cloudstack.storage.command.CopyCmdAnswer;
@@ -166,7 +165,7 @@ public class TemplateObject implements TemplateInfo {
}
@Override
- public void processEvent(Event event) {
+ public void processEvent(org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event event) {
try {
objectInStoreMgr.update(this, event);
} catch (NoTransitionException e) {
@@ -459,4 +458,21 @@ public class TemplateObject implements TemplateInfo {
public Class<?> getEntityType() {
return VirtualMachineTemplate.class;
}
+
+ @Override
+ public long getUpdatedCount() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public void incrUpdatedCount() {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public Date getUpdated() {
+ // TODO Auto-generated method stub
+ return null;
+ }
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/053c160b/engine/storage/src/org/apache/cloudstack/storage/image/TemplateEntityImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/TemplateEntityImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/TemplateEntityImpl.java
index c1aa8c2..db752fe 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/image/TemplateEntityImpl.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/image/TemplateEntityImpl.java
@@ -290,4 +290,21 @@ public class TemplateEntityImpl implements TemplateEntity {
public Class<?> getEntityType() {
return VirtualMachineTemplate.class;
}
+
+ @Override
+ public long getUpdatedCount() {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+ @Override
+ public void incrUpdatedCount() {
+ // TODO Auto-generated method stub
+ }
+
+ @Override
+ public Date getUpdated() {
+ // TODO Auto-generated method stub
+ return null;
+ }
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/053c160b/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java
index dad0b6d..1c3f485 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/TemplateDataStoreDaoImpl.java
@@ -28,7 +28,6 @@ import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Component;
-
import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectInStore;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
@@ -45,7 +44,9 @@ import com.cloud.storage.Storage.TemplateType;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.dao.VMTemplateDao;
+import com.cloud.template.VirtualMachineTemplate;
import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.JoinBuilder.JoinType;
import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.SearchCriteria.Op;
@@ -65,6 +66,8 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase<TemplateDataStoreVO
private SearchBuilder<TemplateDataStoreVO> storeTemplateStateSearch;
private SearchBuilder<TemplateDataStoreVO> storeTemplateDownloadStatusSearch;
private SearchBuilder<TemplateDataStoreVO> downloadTemplateSearch;
+ private SearchBuilder<TemplateDataStoreVO> uploadTemplateStateSearch;
+ private SearchBuilder<VMTemplateVO> templateOnlySearch;
private static final String EXPIRE_DOWNLOAD_URLS_FOR_ZONE = "update template_store_ref set download_url_created=? where store_id in (select id from image_store where data_center_id=?)";
@Inject
@@ -139,6 +142,13 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase<TemplateDataStoreVO
downloadTemplateSearch.and("destroyed", downloadTemplateSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
downloadTemplateSearch.done();
+ templateOnlySearch = _tmpltDao.createSearchBuilder();
+ templateOnlySearch.and("states", templateOnlySearch.entity().getState(), SearchCriteria.Op.IN);
+ uploadTemplateStateSearch = createSearchBuilder();
+ uploadTemplateStateSearch.join("templateOnlySearch", templateOnlySearch, templateOnlySearch.entity().getId(), uploadTemplateStateSearch.entity().getTemplateId(), JoinType.LEFT);
+ uploadTemplateStateSearch.and("destroyed", uploadTemplateStateSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
+ uploadTemplateStateSearch.done();
+
return true;
}
@@ -531,4 +541,11 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase<TemplateDataStoreVO
}
+ @Override
+ public List<TemplateDataStoreVO> listByTemplateState(VirtualMachineTemplate.State... states) {
+ SearchCriteria<TemplateDataStoreVO> sc = uploadTemplateStateSearch.create();
+ sc.setJoinParameters("templateOnlySearch", "states", (Object[])states);
+ sc.setParameters("destroyed", false);
+ return listIncludingRemovedBy(sc);
+ }
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/053c160b/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java b/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java
index 117e622..f3163ee 100644
--- a/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java
+++ b/engine/storage/src/org/apache/cloudstack/storage/image/db/VolumeDataStoreDaoImpl.java
@@ -110,7 +110,7 @@ public class VolumeDataStoreDaoImpl extends GenericDaoBase<VolumeDataStoreVO, Lo
uploadVolumeSearch.done();
volumeOnlySearch = volumeDao.createSearchBuilder();
- volumeOnlySearch.and("state", volumeOnlySearch.entity().getState(), Op.IN);
+ volumeOnlySearch.and("states", volumeOnlySearch.entity().getState(), Op.IN);
uploadVolumeStateSearch = createSearchBuilder();
uploadVolumeStateSearch.join("volumeOnlySearch", volumeOnlySearch, volumeOnlySearch.entity().getId(), uploadVolumeStateSearch.entity().getVolumeId(), JoinType.LEFT);
uploadVolumeStateSearch.and("destroyed", uploadVolumeStateSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
@@ -322,7 +322,7 @@ public class VolumeDataStoreDaoImpl extends GenericDaoBase<VolumeDataStoreVO, Lo
@Override
public List<VolumeDataStoreVO> listByVolumeState(Volume.State... states) {
SearchCriteria<VolumeDataStoreVO> sc = uploadVolumeStateSearch.create();
- sc.setJoinParameters("volumeOnlySearch", "state", (Object[])states);
+ sc.setJoinParameters("volumeOnlySearch", "states", (Object[])states);
sc.setParameters("destroyed", false);
return listIncludingRemovedBy(sc);
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/053c160b/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java b/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java
index 6defb89..63642f0 100755
--- a/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java
+++ b/server/src/com/cloud/storage/ImageStoreUploadMonitorImpl.java
@@ -38,6 +38,8 @@ import org.apache.cloudstack.managed.context.ManagedContextRunnable;
import org.apache.cloudstack.storage.command.UploadStatusAnswer;
import org.apache.cloudstack.storage.command.UploadStatusCommand;
import org.apache.cloudstack.storage.command.UploadStatusCommand.EntityType;
+import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
+import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreDao;
import org.apache.cloudstack.storage.datastore.db.VolumeDataStoreVO;
import org.apache.cloudstack.utils.identity.ManagementServerNode;
@@ -53,7 +55,9 @@ import com.cloud.host.Host;
import com.cloud.host.Status;
import com.cloud.host.dao.HostDao;
import com.cloud.storage.Volume.Event;
+import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VolumeDao;
+import com.cloud.template.VirtualMachineTemplate;
import com.cloud.utils.component.ManagerBase;
import com.cloud.utils.concurrency.NamedThreadFactory;
import com.cloud.utils.db.Transaction;
@@ -76,6 +80,10 @@ public class ImageStoreUploadMonitorImpl extends ManagerBase implements ImageSto
@Inject
private VolumeDataStoreDao _volumeDataStoreDao;
@Inject
+ private VMTemplateDao _templateDao;
+ @Inject
+ private TemplateDataStoreDao _templateDataStoreDao;
+ @Inject
private HostDao _hostDao;
@Inject
private EndPointSelector _epSelector;
@@ -189,6 +197,32 @@ public class ImageStoreUploadMonitorImpl extends ManagerBase implements ImageSto
handleVolumeStatusResponse((UploadStatusAnswer)answer, volume, volumeDataStore);
}
}
+
+ // Handle for template upload as well
+ List<TemplateDataStoreVO> templateDataStores = _templateDataStoreDao.listByTemplateState(VirtualMachineTemplate.State.NotUploaded, VirtualMachineTemplate.State.UploadInProgress);
+ for (TemplateDataStoreVO templateDataStore : templateDataStores) {
+ DataStore dataStore = storeMgr.getDataStore(templateDataStore.getDataStoreId(), DataStoreRole.Image);
+ EndPoint ep = _epSelector.select(dataStore, templateDataStore.getExtractUrl());
+ if (ep == null) {
+ s_logger.warn("There is no secondary storage VM for image store " + dataStore.getName());
+ continue;
+ }
+ VMTemplateVO template = _templateDao.findById(templateDataStore.getTemplateId());
+ if (template == null) {
+ s_logger.warn("Template with id " + templateDataStore.getTemplateId() + " not found");
+ continue;
+ }
+ Host host = _hostDao.findById(ep.getId());
+ if (host != null && host.getManagementServerId() != null && _nodeId == host.getManagementServerId().longValue()) {
+ UploadStatusCommand cmd = new UploadStatusCommand(template.getId(), EntityType.Template);
+ Answer answer = ep.sendMessage(cmd);
+ if (answer == null || !(answer instanceof UploadStatusAnswer)) {
+ s_logger.warn("No or invalid answer corresponding to UploadStatusCommand for template " + templateDataStore.getTemplateId());
+ continue;
+ }
+ handleTemplateStatusResponse((UploadStatusAnswer)answer, template, templateDataStore);
+ }
+ }
}
private void handleVolumeStatusResponse(final UploadStatusAnswer answer, final VolumeVO volume, final VolumeDataStoreVO volumeDataStore) {
@@ -248,6 +282,64 @@ public class ImageStoreUploadMonitorImpl extends ManagerBase implements ImageSto
}
});
}
+
+ private void handleTemplateStatusResponse(final UploadStatusAnswer answer, final VMTemplateVO template, final TemplateDataStoreVO templateDataStore) {
+ final StateMachine2<VirtualMachineTemplate.State, VirtualMachineTemplate.Event, VirtualMachineTemplate> stateMachine = VirtualMachineTemplate.State.getStateMachine();
+ Transaction.execute(new TransactionCallbackNoReturn() {
+ @Override
+ public void doInTransactionWithoutResult(TransactionStatus status) {
+ VMTemplateVO tmpTemplate = _templateDao.findById(template.getId());
+ TemplateDataStoreVO tmpTemplateDataStore = _templateDataStoreDao.findById(templateDataStore.getId());
+ try {
+ switch (answer.getStatus()) {
+ case COMPLETED:
+ tmpTemplateDataStore.setDownloadState(VMTemplateStorageResourceAssoc.Status.UPLOADED);
+ stateMachine.transitTo(tmpTemplate, VirtualMachineTemplate.Event.OperationSucceeded, null, _templateDao);
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Template " + tmpTemplate.getUuid() + " uploaded successfully");
+ }
+ break;
+ case IN_PROGRESS:
+ if (tmpTemplate.getState() == VirtualMachineTemplate.State.NotUploaded) {
+ tmpTemplateDataStore.setDownloadState(VMTemplateStorageResourceAssoc.Status.UPLOAD_IN_PROGRESS);
+ stateMachine.transitTo(tmpTemplate, VirtualMachineTemplate.Event.UploadRequested, null, _templateDao);
+ } else if (tmpTemplate.getState() == VirtualMachineTemplate.State.UploadInProgress) { // check for timeout
+ if (System.currentTimeMillis() - tmpTemplateDataStore.getCreated().getTime() > _uploadOperationTimeout) {
+ tmpTemplateDataStore.setDownloadState(VMTemplateStorageResourceAssoc.Status.UPLOAD_ERROR);
+ stateMachine.transitTo(tmpTemplate, VirtualMachineTemplate.Event.OperationFailed, null, _templateDao);
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Template " + tmpTemplate.getUuid() + " failed to upload due to operation timed out");
+ }
+ }
+ }
+ break;
+ case ERROR:
+ tmpTemplateDataStore.setDownloadState(VMTemplateStorageResourceAssoc.Status.UPLOAD_ERROR);
+ stateMachine.transitTo(tmpTemplate, VirtualMachineTemplate.Event.OperationFailed, null, _templateDao);
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Template " + tmpTemplate.getUuid() + " failed to upload. Error details: " + answer.getDetails());
+ }
+ break;
+ case UNKNOWN:
+ if (tmpTemplate.getState() == VirtualMachineTemplate.State.NotUploaded) { // check for timeout
+ if (System.currentTimeMillis() - tmpTemplateDataStore.getCreated().getTime() > _uploadOperationTimeout) {
+ tmpTemplateDataStore.setDownloadState(VMTemplateStorageResourceAssoc.Status.ABANDONED);
+ stateMachine.transitTo(tmpTemplate, VirtualMachineTemplate.Event.OperationTimeout, null, _templateDao);
+ if (s_logger.isDebugEnabled()) {
+ s_logger.debug("Template " + tmpTemplate.getUuid() + " failed to upload due to operation timed out");
+ }
+ }
+ }
+ break;
+ }
+ _templateDataStoreDao.update(tmpTemplateDataStore.getId(), tmpTemplateDataStore);
+ } catch (NoTransitionException e) {
+ s_logger.error("Unexpected error " + e.getMessage());
+ }
+ }
+ });
+ }
+
}
@Override