diff --git a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java index 5f33a492027..10734673e4e 100644 --- a/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java +++ b/plugins/storage/image/s3/src/org/apache/cloudstack/storage/datastore/driver/S3ImageStoreDriverImpl.java @@ -33,10 +33,11 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; -import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.cloudstack.storage.image.store.ImageStoreImpl; import org.apache.cloudstack.storage.image.store.TemplateObject; @@ -46,10 +47,13 @@ import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.DeleteSnapshotBackupCommand; +import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.DeleteVolumeCommand; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.S3TO; import com.cloud.agent.api.to.SwiftTO; +import com.cloud.event.EventTypes; +import com.cloud.event.UsageEventUtils; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.storage.RegisterVolumePayload; @@ -68,9 +72,14 @@ import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.dao.VolumeHostDao; import com.cloud.storage.download.DownloadMonitor; import com.cloud.storage.s3.S3Manager; +import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.storage.swift.SwiftManager; +import com.cloud.user.Account; +import com.cloud.user.dao.AccountDao; import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.vm.UserVmVO; +import com.cloud.vm.dao.UserVmDao; public class S3ImageStoreDriverImpl implements ImageStoreDriver { private static final Logger s_logger = Logger @@ -94,6 +103,14 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { private SwiftManager _swiftMgr; @Inject private S3Manager _s3Mgr; + @Inject AccountDao _accountDao; + @Inject UserVmDao _userVmDao; + @Inject + SecondaryStorageVmManager _ssvmMgr; + @Inject + private AgentManager _agentMgr; + @Inject TemplateDataStoreDao _templateStoreDao; + @Override public String grantAccess(DataObject data, EndPoint ep) { // TODO Auto-generated method stub @@ -197,7 +214,61 @@ public class S3ImageStoreDriverImpl implements ImageStoreDriver { } private void deleteTemplate(DataObject data, AsyncCompletionCallback callback) { + TemplateObject templateObj = (TemplateObject) data; + VMTemplateVO template = templateObj.getImage(); + ImageStoreImpl store = (ImageStoreImpl) templateObj.getDataStore(); + long storeId = store.getId(); + Long sZoneId = store.getDataCenterId(); + long templateId = template.getId(); + Account account = _accountDao.findByIdIncludingRemoved(template.getAccountId()); + String eventType = ""; + + if (template.getFormat().equals(ImageFormat.ISO)) { + eventType = EventTypes.EVENT_ISO_DELETE; + } else { + eventType = EventTypes.EVENT_TEMPLATE_DELETE; + } + + // TODO: need to understand why we need to mark destroyed in + // template_store_ref table here instead of in callback. + // Currently I did that in callback, so I removed previous code to mark template_host_ref + + UsageEventUtils.publishUsageEvent(eventType, account.getId(), sZoneId, templateId, null, null, null); + + List userVmUsingIso = _userVmDao.listByIsoId(templateId); + // check if there is any VM using this ISO. + if (userVmUsingIso == null || userVmUsingIso.isEmpty()) { + // get installpath of this template on image store + TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId); + String installPath = tmplStore.getInstallPath(); + if (installPath != null) { + Answer answer = _agentMgr.sendToSecStorage(store, new DeleteTemplateCommand(store.getTO(), store.getUri(), installPath, template.getId(), template.getAccountId())); + + if (answer == null || !answer.getResult()) { + s_logger.debug("Failed to deleted template at store: " + store.getName()); + CommandResult result = new CommandResult(); + result.setSucess(false); + result.setResult("Delete template failed"); + callback.complete(result); + + } else { + s_logger.debug("Deleted template at: " + installPath); + CommandResult result = new CommandResult(); + result.setSucess(false); + callback.complete(result); + } + + // for S3, a template can be associated with multiple zones + List templateZones = templateZoneDao + .listByZoneTemplate(sZoneId, templateId); + if (templateZones != null) { + for (VMTemplateZoneVO templateZone : templateZones) { + templateZoneDao.remove(templateZone.getId()); + } + } + } + } } private void deleteSnapshot(DataObject data, AsyncCompletionCallback callback) { diff --git a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java index e96bfffa6a2..88405d284ba 100644 --- a/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java +++ b/plugins/storage/image/swift/src/org/apache/cloudstack/storage/datastore/driver/SwiftImageStoreDriverImpl.java @@ -33,10 +33,11 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataObjectType; import org.apache.cloudstack.engine.subsystem.api.storage.DataStore; import org.apache.cloudstack.engine.subsystem.api.storage.DataTO; import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint; -import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo; import org.apache.cloudstack.framework.async.AsyncCompletionCallback; import org.apache.cloudstack.framework.async.AsyncRpcConext; import org.apache.cloudstack.storage.datastore.db.ImageStoreDetailsDao; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao; +import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO; import org.apache.cloudstack.storage.image.ImageStoreDriver; import org.apache.cloudstack.storage.image.store.ImageStoreImpl; import org.apache.cloudstack.storage.image.store.TemplateObject; @@ -46,10 +47,13 @@ import org.apache.log4j.Logger; import com.cloud.agent.AgentManager; import com.cloud.agent.api.Answer; import com.cloud.agent.api.DeleteSnapshotBackupCommand; +import com.cloud.agent.api.storage.DeleteTemplateCommand; import com.cloud.agent.api.storage.DeleteVolumeCommand; import com.cloud.agent.api.to.DataStoreTO; import com.cloud.agent.api.to.S3TO; import com.cloud.agent.api.to.SwiftTO; +import com.cloud.event.EventTypes; +import com.cloud.event.UsageEventUtils; import com.cloud.host.HostVO; import com.cloud.host.dao.HostDao; import com.cloud.storage.RegisterVolumePayload; @@ -68,9 +72,14 @@ import com.cloud.storage.dao.VolumeDao; import com.cloud.storage.dao.VolumeHostDao; import com.cloud.storage.download.DownloadMonitor; import com.cloud.storage.s3.S3Manager; +import com.cloud.storage.secondary.SecondaryStorageVmManager; import com.cloud.storage.snapshot.SnapshotManager; import com.cloud.storage.swift.SwiftManager; +import com.cloud.user.Account; +import com.cloud.user.dao.AccountDao; import com.cloud.utils.exception.CloudRuntimeException; +import com.cloud.vm.UserVmVO; +import com.cloud.vm.dao.UserVmDao; public class SwiftImageStoreDriverImpl implements ImageStoreDriver { private static final Logger s_logger = Logger @@ -94,6 +103,14 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { private SwiftManager _swiftMgr; @Inject private S3Manager _s3Mgr; + @Inject AccountDao _accountDao; + @Inject UserVmDao _userVmDao; + @Inject + SecondaryStorageVmManager _ssvmMgr; + @Inject + private AgentManager _agentMgr; + @Inject TemplateDataStoreDao _templateStoreDao; + @Override public String grantAccess(DataObject data, EndPoint ep) { // TODO Auto-generated method stub @@ -190,7 +207,61 @@ public class SwiftImageStoreDriverImpl implements ImageStoreDriver { } private void deleteTemplate(DataObject data, AsyncCompletionCallback callback) { + TemplateObject templateObj = (TemplateObject) data; + VMTemplateVO template = templateObj.getImage(); + ImageStoreImpl store = (ImageStoreImpl) templateObj.getDataStore(); + long storeId = store.getId(); + Long sZoneId = store.getDataCenterId(); + long templateId = template.getId(); + Account account = _accountDao.findByIdIncludingRemoved(template.getAccountId()); + String eventType = ""; + + if (template.getFormat().equals(ImageFormat.ISO)) { + eventType = EventTypes.EVENT_ISO_DELETE; + } else { + eventType = EventTypes.EVENT_TEMPLATE_DELETE; + } + + // TODO: need to understand why we need to mark destroyed in + // template_store_ref table here instead of in callback. + // Currently I did that in callback, so I removed previous code to mark template_host_ref + + UsageEventUtils.publishUsageEvent(eventType, account.getId(), sZoneId, templateId, null, null, null); + + List userVmUsingIso = _userVmDao.listByIsoId(templateId); + // check if there is any VM using this ISO. + if (userVmUsingIso == null || userVmUsingIso.isEmpty()) { + // get installpath of this template on image store + TemplateDataStoreVO tmplStore = _templateStoreDao.findByStoreTemplate(storeId, templateId); + String installPath = tmplStore.getInstallPath(); + if (installPath != null) { + Answer answer = _agentMgr.sendToSecStorage(store, new DeleteTemplateCommand(store.getTO(), store.getUri(), installPath, template.getId(), template.getAccountId())); + + if (answer == null || !answer.getResult()) { + s_logger.debug("Failed to deleted template at store: " + store.getName()); + CommandResult result = new CommandResult(); + result.setSucess(false); + result.setResult("Delete template failed"); + callback.complete(result); + + } else { + s_logger.debug("Deleted template at: " + installPath); + CommandResult result = new CommandResult(); + result.setSucess(false); + callback.complete(result); + } + + // for Swift, a template can be associated with multiple zones + List templateZones = templateZoneDao + .listByZoneTemplate(sZoneId, templateId); + if (templateZones != null) { + for (VMTemplateZoneVO templateZone : templateZones) { + templateZoneDao.remove(templateZone.getId()); + } + } + } + } } private void deleteSnapshot(DataObject data, AsyncCompletionCallback callback) { diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index e9729e4ff31..da0b884ecd5 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -1487,34 +1487,10 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager, if (template.getFormat() == ImageFormat.ISO) { throw new InvalidParameterValueException("Please specify a valid template."); } - /* - if (cmd.getZoneId() == null && _swiftMgr.isSwiftEnabled()) { - _swiftMgr.deleteTemplate(cmd); - } - if (cmd.getZoneId() == null && _s3Mgr.isS3Enabled()) { - _s3Mgr.deleteTemplate(cmd.getId(), caller.getAccountId()); - } - */ TemplateAdapter adapter = getAdapter(template.getHypervisorType()); TemplateProfile profile = adapter.prepareDelete(cmd); - boolean result = adapter.delete(profile); - - if (result){ - if (cmd.getZoneId() == null - && (_swiftMgr.isSwiftEnabled() || _s3Mgr.isS3Enabled())) { - List templateZones = _tmpltZoneDao - .listByZoneTemplate(null, templateId); - if (templateZones != null) { - for (VMTemplateZoneVO templateZone : templateZones) { - _tmpltZoneDao.remove(templateZone.getId()); - } - } - } - return true; - }else{ - throw new CloudRuntimeException("Failed to delete template"); - } + return adapter.delete(profile); } @Override