mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Fix the flow of deleteTemplateCmd.
This commit is contained in:
parent
593337565e
commit
0da2da852b
@ -16,17 +16,26 @@
|
|||||||
// under the License.
|
// under the License.
|
||||||
package com.cloud.agent.api.storage;
|
package com.cloud.agent.api.storage;
|
||||||
|
|
||||||
|
import com.cloud.agent.api.to.DataStoreTO;
|
||||||
|
|
||||||
|
|
||||||
public class DeleteTemplateCommand extends ssCommand {
|
public class DeleteTemplateCommand extends ssCommand {
|
||||||
|
private DataStoreTO store;
|
||||||
private String templatePath;
|
private String templatePath;
|
||||||
|
private Long templateId;
|
||||||
|
private Long accountId;
|
||||||
|
|
||||||
|
|
||||||
public DeleteTemplateCommand() {
|
public DeleteTemplateCommand() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public DeleteTemplateCommand(String secUrl, String templatePath) {
|
|
||||||
|
public DeleteTemplateCommand(DataStoreTO store, String secUrl, String templatePath, Long templateId, Long accountId) {
|
||||||
this.setSecUrl(secUrl);
|
this.setSecUrl(secUrl);
|
||||||
this.templatePath = templatePath;
|
this.templatePath = templatePath;
|
||||||
|
this.templateId = templateId;
|
||||||
|
this.accountId = accountId;
|
||||||
|
this.store = store;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -37,4 +46,18 @@ public class DeleteTemplateCommand extends ssCommand {
|
|||||||
public String getTemplatePath() {
|
public String getTemplatePath() {
|
||||||
return templatePath;
|
return templatePath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Long getTemplateId() {
|
||||||
|
return templateId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getAccountId() {
|
||||||
|
return accountId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataStoreTO getDataStore() {
|
||||||
|
return store;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -128,19 +128,16 @@ public class VMTemplateVO implements VirtualMachineTemplate, StateObject<Templat
|
|||||||
|
|
||||||
@Column(name="enable_sshkey")
|
@Column(name="enable_sshkey")
|
||||||
private boolean enableSshKey;
|
private boolean enableSshKey;
|
||||||
|
|
||||||
@Column(name = "image_data_store_id")
|
|
||||||
private long imageDataStoreId;
|
|
||||||
|
|
||||||
@Column(name = "size")
|
@Column(name = "size")
|
||||||
private Long size;
|
private Long size;
|
||||||
|
|
||||||
@Column(name = "state")
|
@Column(name = "state")
|
||||||
private TemplateState state;
|
private TemplateState state;
|
||||||
|
|
||||||
@Column(name="update_count", updatable = true)
|
@Column(name="update_count", updatable = true)
|
||||||
protected long updatedCount;
|
protected long updatedCount;
|
||||||
|
|
||||||
@Column(name = "updated")
|
@Column(name = "updated")
|
||||||
@Temporal(value = TemporalType.TIMESTAMP)
|
@Temporal(value = TemporalType.TIMESTAMP)
|
||||||
Date updated;
|
Date updated;
|
||||||
@ -489,31 +486,24 @@ public class VMTemplateVO implements VirtualMachineTemplate, StateObject<Templat
|
|||||||
public void setEnableSshKey(boolean enable) {
|
public void setEnableSshKey(boolean enable) {
|
||||||
enableSshKey = enable;
|
enableSshKey = enable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getImageDataStoreId() {
|
|
||||||
return this.imageDataStoreId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setImageDataStoreId(long dataStoreId) {
|
|
||||||
this.imageDataStoreId = dataStoreId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSize(Long size) {
|
public void setSize(Long size) {
|
||||||
this.size = size;
|
this.size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getSize() {
|
public Long getSize() {
|
||||||
return this.size;
|
return this.size;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TemplateState getState() {
|
public TemplateState getState() {
|
||||||
return this.state;
|
return this.state;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getUpdatedCount() {
|
public long getUpdatedCount() {
|
||||||
return this.updatedCount;
|
return this.updatedCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void incrUpdatedCount() {
|
public void incrUpdatedCount() {
|
||||||
this.updatedCount++;
|
this.updatedCount++;
|
||||||
}
|
}
|
||||||
@ -521,11 +511,11 @@ public class VMTemplateVO implements VirtualMachineTemplate, StateObject<Templat
|
|||||||
public void decrUpdatedCount() {
|
public void decrUpdatedCount() {
|
||||||
this.updatedCount--;
|
this.updatedCount--;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Date getUpdated() {
|
public Date getUpdated() {
|
||||||
return updated;
|
return updated;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUpdated(Date updated) {
|
public void setUpdated(Date updated) {
|
||||||
this.updated = updated;
|
this.updated = updated;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -371,7 +371,7 @@ SecondaryStorageResource {
|
|||||||
return new Answer(cmd, false, "Swift is not currently support DownloadCommand");
|
return new Answer(cmd, false, "Swift is not currently support DownloadCommand");
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
return new Answer(cmd, false, "Unsupport image data store: " + dstore);
|
return new Answer(cmd, false, "Unsupported image data store: " + dstore);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -504,6 +504,8 @@ SecondaryStorageResource {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private Answer execute(final DeleteTemplateFromS3Command cmd) {
|
private Answer execute(final DeleteTemplateFromS3Command cmd) {
|
||||||
|
|
||||||
final S3TO s3 = cmd.getS3();
|
final S3TO s3 = cmd.getS3();
|
||||||
@ -1318,51 +1320,107 @@ SecondaryStorageResource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Answer execute(final DeleteTemplateCommand cmd) {
|
protected Answer execute(final DeleteTemplateCommand cmd) {
|
||||||
String relativeTemplatePath = cmd.getTemplatePath();
|
DataStoreTO dstore = cmd.getDataStore();
|
||||||
String parent = getRootDir(cmd);
|
if (dstore instanceof NfsTO) {
|
||||||
|
String relativeTemplatePath = cmd.getTemplatePath();
|
||||||
|
String parent = getRootDir(cmd);
|
||||||
|
|
||||||
if (relativeTemplatePath.startsWith(File.separator)) {
|
if (relativeTemplatePath.startsWith(File.separator)) {
|
||||||
relativeTemplatePath = relativeTemplatePath.substring(1);
|
relativeTemplatePath = relativeTemplatePath.substring(1);
|
||||||
}
|
|
||||||
|
|
||||||
if (!parent.endsWith(File.separator)) {
|
|
||||||
parent += File.separator;
|
|
||||||
}
|
|
||||||
String absoluteTemplatePath = parent + relativeTemplatePath;
|
|
||||||
File tmpltParent = new File(absoluteTemplatePath).getParentFile();
|
|
||||||
String details = null;
|
|
||||||
if (!tmpltParent.exists()) {
|
|
||||||
details = "template parent directory " + tmpltParent.getName() + " doesn't exist";
|
|
||||||
s_logger.debug(details);
|
|
||||||
return new Answer(cmd, true, details);
|
|
||||||
}
|
|
||||||
File[] tmpltFiles = tmpltParent.listFiles();
|
|
||||||
if (tmpltFiles == null || tmpltFiles.length == 0) {
|
|
||||||
details = "No files under template parent directory " + tmpltParent.getName();
|
|
||||||
s_logger.debug(details);
|
|
||||||
} else {
|
|
||||||
boolean found = false;
|
|
||||||
for (File f : tmpltFiles) {
|
|
||||||
if (!found && f.getName().equals("template.properties")) {
|
|
||||||
found = true;
|
|
||||||
}
|
|
||||||
if (!f.delete()) {
|
|
||||||
return new Answer(cmd, false, "Unable to delete file " + f.getName() + " under Template path "
|
|
||||||
+ relativeTemplatePath);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!found) {
|
|
||||||
details = "Can not find template.properties under " + tmpltParent.getName();
|
if (!parent.endsWith(File.separator)) {
|
||||||
|
parent += File.separator;
|
||||||
|
}
|
||||||
|
String absoluteTemplatePath = parent + relativeTemplatePath;
|
||||||
|
File tmpltParent = new File(absoluteTemplatePath).getParentFile();
|
||||||
|
String details = null;
|
||||||
|
if (!tmpltParent.exists()) {
|
||||||
|
details = "template parent directory " + tmpltParent.getName() + " doesn't exist";
|
||||||
s_logger.debug(details);
|
s_logger.debug(details);
|
||||||
|
return new Answer(cmd, true, details);
|
||||||
|
}
|
||||||
|
File[] tmpltFiles = tmpltParent.listFiles();
|
||||||
|
if (tmpltFiles == null || tmpltFiles.length == 0) {
|
||||||
|
details = "No files under template parent directory " + tmpltParent.getName();
|
||||||
|
s_logger.debug(details);
|
||||||
|
} else {
|
||||||
|
boolean found = false;
|
||||||
|
for (File f : tmpltFiles) {
|
||||||
|
if (!found && f.getName().equals("template.properties")) {
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
if (!f.delete()) {
|
||||||
|
return new Answer(cmd, false, "Unable to delete file " + f.getName() + " under Template path " + relativeTemplatePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found) {
|
||||||
|
details = "Can not find template.properties under " + tmpltParent.getName();
|
||||||
|
s_logger.debug(details);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!tmpltParent.delete()) {
|
||||||
|
details = "Unable to delete directory " + tmpltParent.getName() + " under Template path " + relativeTemplatePath;
|
||||||
|
s_logger.debug(details);
|
||||||
|
return new Answer(cmd, false, details);
|
||||||
|
}
|
||||||
|
return new Answer(cmd, true, null);
|
||||||
|
}
|
||||||
|
else if (dstore instanceof S3TO ){
|
||||||
|
final S3TO s3 = (S3TO)dstore;
|
||||||
|
final Long accountId = cmd.getAccountId();
|
||||||
|
final Long templateId = cmd.getTemplateId();
|
||||||
|
|
||||||
|
if (accountId == null || (accountId != null && accountId <= 0)) {
|
||||||
|
final String errorMessage = "No account id specified for S3 template deletion.";
|
||||||
|
s_logger.error(errorMessage);
|
||||||
|
return new Answer(cmd, false, errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (templateId == null || (templateId != null && templateId <= 0)) {
|
||||||
|
final String errorMessage = "No template id specified for S3 template deletion.";
|
||||||
|
s_logger.error(errorMessage);
|
||||||
|
return new Answer(cmd, false, errorMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
final String bucket = s3.getBucketName();
|
||||||
|
try {
|
||||||
|
S3Utils.deleteDirectory(s3, bucket,
|
||||||
|
determineS3TemplateDirectory(templateId, accountId));
|
||||||
|
return new Answer(cmd, true, String.format(
|
||||||
|
"Deleted template %1%s from bucket %2$s.", templateId,
|
||||||
|
bucket));
|
||||||
|
} catch (Exception e) {
|
||||||
|
final String errorMessage = String
|
||||||
|
.format("Failed to delete templaet id %1$s from bucket %2$s due to the following error: %3$s",
|
||||||
|
templateId, bucket, e.getMessage());
|
||||||
|
s_logger.error(errorMessage, e);
|
||||||
|
return new Answer(cmd, false, errorMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!tmpltParent.delete()) {
|
else if (dstore instanceof SwiftTO){
|
||||||
details = "Unable to delete directory " + tmpltParent.getName() + " under Template path "
|
SwiftTO swift = (SwiftTO)dstore;
|
||||||
+ relativeTemplatePath;
|
String container = "T-" + cmd.getTemplateId();
|
||||||
s_logger.debug(details);
|
String object = "";
|
||||||
return new Answer(cmd, false, details);
|
|
||||||
|
try {
|
||||||
|
String result = swiftDelete(swift, container, object);
|
||||||
|
if (result != null) {
|
||||||
|
String errMsg = "failed to delete object " + container + "/" + object + " , err=" + result;
|
||||||
|
s_logger.warn(errMsg);
|
||||||
|
return new Answer(cmd, false, errMsg);
|
||||||
|
}
|
||||||
|
return new Answer(cmd, true, "success");
|
||||||
|
} catch (Exception e) {
|
||||||
|
String errMsg = cmd + " Command failed due to " + e.toString();
|
||||||
|
s_logger.warn(errMsg, e);
|
||||||
|
return new Answer(cmd, false, errMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
return new Answer(cmd, false, "Unsupported image data store: " + dstore);
|
||||||
}
|
}
|
||||||
return new Answer(cmd, true, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Answer execute(final DeleteVolumeCommand cmd) {
|
protected Answer execute(final DeleteVolumeCommand cmd) {
|
||||||
|
|||||||
@ -32,11 +32,19 @@ public interface TemplateDataStoreDao extends GenericDao<TemplateDataStoreVO, Lo
|
|||||||
|
|
||||||
public List<TemplateDataStoreVO> listByStoreId(long id);
|
public List<TemplateDataStoreVO> listByStoreId(long id);
|
||||||
|
|
||||||
|
public List<TemplateDataStoreVO> listDestroyed(long storeId);
|
||||||
|
|
||||||
public void deletePrimaryRecordsForStore(long id);
|
public void deletePrimaryRecordsForStore(long id);
|
||||||
|
|
||||||
|
List<TemplateDataStoreVO> listByTemplateStore(long templateId, long storeId);
|
||||||
|
|
||||||
List<TemplateDataStoreVO> listByTemplateStoreStatus(long templateId, long storeId, State... states);
|
List<TemplateDataStoreVO> listByTemplateStoreStatus(long templateId, long storeId, State... states);
|
||||||
|
|
||||||
List<TemplateDataStoreVO> listByTemplateStoreDownloadStatus(long templateId, long storeId, Status... status);
|
List<TemplateDataStoreVO> listByTemplateStoreDownloadStatus(long templateId, long storeId, Status... status);
|
||||||
|
|
||||||
TemplateDataStoreVO findByStoreTemplate(long storeId, long templateId);
|
TemplateDataStoreVO findByStoreTemplate(long storeId, long templateId);
|
||||||
|
|
||||||
|
TemplateDataStoreVO findByTemplate(long templateId);
|
||||||
|
|
||||||
|
List<TemplateDataStoreVO> listByTemplate(long templateId);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -28,6 +28,8 @@ import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
|
|||||||
import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory;
|
import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
|
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
|
||||||
import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager;
|
import org.apache.cloudstack.storage.datastore.ObjectInDataStoreManager;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
|
||||||
import org.apache.cloudstack.storage.image.store.TemplateObject;
|
import org.apache.cloudstack.storage.image.store.TemplateObject;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@ -50,6 +52,8 @@ public class ImageDataFactoryImpl implements ImageDataFactory {
|
|||||||
DataStoreManager storeMgr;
|
DataStoreManager storeMgr;
|
||||||
@Inject
|
@Inject
|
||||||
VMTemplatePoolDao templatePoolDao;
|
VMTemplatePoolDao templatePoolDao;
|
||||||
|
@Inject
|
||||||
|
TemplateDataStoreDao templateStoreDao;
|
||||||
@Override
|
@Override
|
||||||
public TemplateInfo getTemplate(long templateId, DataStore store) {
|
public TemplateInfo getTemplate(long templateId, DataStore store) {
|
||||||
VMTemplateVO templ = imageDataDao.findById(templateId);
|
VMTemplateVO templ = imageDataDao.findById(templateId);
|
||||||
@ -77,13 +81,17 @@ public class ImageDataFactoryImpl implements ImageDataFactory {
|
|||||||
TemplateObject tmpl = TemplateObject.getTemplate(templ, store);
|
TemplateObject tmpl = TemplateObject.getTemplate(templ, store);
|
||||||
return tmpl;
|
return tmpl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: this method is problematic, since one template can be stored in multiple image stores.
|
||||||
|
// need to see if we can get rid of this method or change to plural format.
|
||||||
@Override
|
@Override
|
||||||
public TemplateInfo getTemplate(long templateId) {
|
public TemplateInfo getTemplate(long templateId) {
|
||||||
VMTemplateVO templ = imageDataDao.findById(templateId);
|
VMTemplateVO templ = imageDataDao.findById(templateId);
|
||||||
if (templ.getImageDataStoreId() == null) {
|
TemplateDataStoreVO tmplStore = templateStoreDao.findByTemplate(templateId);
|
||||||
return this.getTemplate(templateId, null);
|
DataStore store = null;
|
||||||
|
if ( tmplStore != null ){
|
||||||
|
store = this.storeMgr.getDataStore(tmplStore.getDataStoreId(), DataStoreRole.Image);
|
||||||
}
|
}
|
||||||
DataStore store = this.storeMgr.getDataStore(templ.getImageDataStoreId(), DataStoreRole.Image);
|
|
||||||
return this.getTemplate(templateId, store);
|
return this.getTemplate(templateId, store);
|
||||||
}
|
}
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@ -40,6 +40,8 @@ import org.apache.cloudstack.engine.subsystem.api.storage.TemplateInfo;
|
|||||||
import com.cloud.storage.template.TemplateProp;
|
import com.cloud.storage.template.TemplateProp;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
|
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
|
import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.ObjectInDataStoreStateMachine.Event;
|
||||||
|
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeService.VolumeApiResult;
|
||||||
import org.apache.cloudstack.framework.async.AsyncCallFuture;
|
import org.apache.cloudstack.framework.async.AsyncCallFuture;
|
||||||
import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
|
import org.apache.cloudstack.framework.async.AsyncCallbackDispatcher;
|
||||||
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
|
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
|
||||||
@ -139,6 +141,28 @@ public class TemplateServiceImpl implements TemplateService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class DeleteTemplateContext<T> extends AsyncRpcConext<T> {
|
||||||
|
final TemplateObject template;
|
||||||
|
final AsyncCallFuture<CommandResult> future;
|
||||||
|
|
||||||
|
public DeleteTemplateContext(AsyncCompletionCallback<T> callback, TemplateObject template,
|
||||||
|
AsyncCallFuture<CommandResult> future) {
|
||||||
|
super(callback);
|
||||||
|
this.template = template;
|
||||||
|
this.future = future;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TemplateObject getTemplate() {
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsyncCallFuture<CommandResult> getFuture() {
|
||||||
|
return future;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public AsyncCallFuture<CommandResult> createTemplateAsync(
|
public AsyncCallFuture<CommandResult> createTemplateAsync(
|
||||||
TemplateInfo template, DataStore store) {
|
TemplateInfo template, DataStore store) {
|
||||||
@ -361,7 +385,8 @@ public class TemplateServiceImpl implements TemplateService {
|
|||||||
List<UserVmVO> userVmUsingIso = _userVmDao.listByIsoId(tInfo.getId());
|
List<UserVmVO> userVmUsingIso = _userVmDao.listByIsoId(tInfo.getId());
|
||||||
//check if there is any Vm using this ISO.
|
//check if there is any Vm using this ISO.
|
||||||
if (userVmUsingIso == null || userVmUsingIso.isEmpty()) {
|
if (userVmUsingIso == null || userVmUsingIso.isEmpty()) {
|
||||||
DeleteTemplateCommand dtCommand = new DeleteTemplateCommand(store.getUri(), tInfo.getInstallPath());
|
VMTemplateVO template = _templateDao.findById(tInfo.getId());
|
||||||
|
DeleteTemplateCommand dtCommand = new DeleteTemplateCommand(store.getTO(), store.getUri(), tInfo.getInstallPath(), template.getId(), template.getAccountId());
|
||||||
try {
|
try {
|
||||||
HostVO ssAhost = _ssvmMgr.pickSsvmHost(store);
|
HostVO ssAhost = _ssvmMgr.pickSsvmHost(store);
|
||||||
_agentMgr.sendToSecStorage(ssAhost, dtCommand, null);
|
_agentMgr.sendToSecStorage(ssAhost, dtCommand, null);
|
||||||
@ -458,7 +483,28 @@ public class TemplateServiceImpl implements TemplateService {
|
|||||||
@Override
|
@Override
|
||||||
public AsyncCallFuture<CommandResult> deleteTemplateAsync(
|
public AsyncCallFuture<CommandResult> deleteTemplateAsync(
|
||||||
TemplateInfo template) {
|
TemplateInfo template) {
|
||||||
// TODO Auto-generated method stub
|
TemplateObject to = (TemplateObject) template;
|
||||||
|
// update template_store_ref status
|
||||||
|
to.processEvent(ObjectInDataStoreStateMachine.Event.DestroyRequested);
|
||||||
|
AsyncCallFuture<CommandResult> future = new AsyncCallFuture<CommandResult>();
|
||||||
|
|
||||||
|
DeleteTemplateContext<CommandResult> context = new DeleteTemplateContext<CommandResult>(null, to, future);
|
||||||
|
AsyncCallbackDispatcher<TemplateServiceImpl, CommandResult> caller = AsyncCallbackDispatcher.create(this);
|
||||||
|
caller.setCallback(caller.getTarget().deleteTemplateCallback(null, null)).setContext(context);
|
||||||
|
to.getDataStore().getDriver().deleteAsync(to, caller);
|
||||||
|
return future;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Void deleteTemplateCallback(AsyncCallbackDispatcher<TemplateServiceImpl, CommandResult> callback, DeleteTemplateContext<CommandResult> context) {
|
||||||
|
CommandResult result = callback.getResult();
|
||||||
|
TemplateObject vo = context.getTemplate();
|
||||||
|
// we can only update state in template_store_ref table
|
||||||
|
if (result.isSuccess()) {
|
||||||
|
vo.processEvent(Event.OperationSuccessed);
|
||||||
|
} else {
|
||||||
|
vo.processEvent(Event.OperationFailed);
|
||||||
|
}
|
||||||
|
context.getFuture().complete(result);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -69,9 +69,6 @@ public class TemplateObject implements TemplateInfo {
|
|||||||
return to;
|
return to;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setImageStoreId(long id) {
|
|
||||||
this.imageVO.setImageDataStoreId(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSize(Long size) {
|
public void setSize(Long size) {
|
||||||
this.imageVO.setSize(size);
|
this.imageVO.setSize(size);
|
||||||
@ -85,7 +82,7 @@ public class TemplateObject implements TemplateInfo {
|
|||||||
public DataStore getDataStore() {
|
public DataStore getDataStore() {
|
||||||
return this.dataStore;
|
return this.dataStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getUniqueName() {
|
public String getUniqueName() {
|
||||||
return this.imageVO.getUniqueName();
|
return this.imageVO.getUniqueName();
|
||||||
@ -126,7 +123,7 @@ public class TemplateObject implements TemplateInfo {
|
|||||||
|
|
||||||
if (templateHostVO == null) {
|
if (templateHostVO == null) {
|
||||||
VMTemplateSwiftVO templateSwiftVO = _swiftMgr.findByTmpltId(templateForVmCreation.getId());
|
VMTemplateSwiftVO templateSwiftVO = _swiftMgr.findByTmpltId(templateForVmCreation.getId());
|
||||||
if (templateSwiftVO != null) {
|
if (templateSwiftVO != null) {
|
||||||
long templateSize = templateSwiftVO.getPhysicalSize();
|
long templateSize = templateSwiftVO.getPhysicalSize();
|
||||||
if (templateSize == 0) {
|
if (templateSize == 0) {
|
||||||
templateSize = templateSwiftVO.getSize();
|
templateSize = templateSwiftVO.getSize();
|
||||||
@ -172,7 +169,7 @@ public class TemplateObject implements TemplateInfo {
|
|||||||
throw new CloudRuntimeException("Failed to update state" + e.toString());
|
throw new CloudRuntimeException("Failed to update state" + e.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void processEvent(ObjectInDataStoreStateMachine.Event event, Answer answer) {
|
public void processEvent(ObjectInDataStoreStateMachine.Event event, Answer answer) {
|
||||||
try {
|
try {
|
||||||
@ -182,14 +179,14 @@ public class TemplateObject implements TemplateInfo {
|
|||||||
throw new CloudRuntimeException("Failed to update state" + e.toString());
|
throw new CloudRuntimeException("Failed to update state" + e.toString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DataTO getTO() {
|
public DataTO getTO() {
|
||||||
DataTO to = this.dataStore.getDriver().getTO(this);
|
DataTO to = this.dataStore.getDriver().getTO(this);
|
||||||
if (to == null) {
|
if (to == null) {
|
||||||
to = new TemplateObjectTO(this);
|
to = new TemplateObjectTO(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
return to;
|
return to;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -43,9 +43,11 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase<TemplateDataStoreVO
|
|||||||
private static final Logger s_logger = Logger.getLogger(TemplateDataStoreDaoImpl.class);
|
private static final Logger s_logger = Logger.getLogger(TemplateDataStoreDaoImpl.class);
|
||||||
private SearchBuilder<TemplateDataStoreVO> updateStateSearch;
|
private SearchBuilder<TemplateDataStoreVO> updateStateSearch;
|
||||||
private SearchBuilder<TemplateDataStoreVO> storeSearch;
|
private SearchBuilder<TemplateDataStoreVO> storeSearch;
|
||||||
|
private SearchBuilder<TemplateDataStoreVO> templateSearch;
|
||||||
|
private SearchBuilder<TemplateDataStoreVO> storeTemplateSearch;
|
||||||
private SearchBuilder<TemplateDataStoreVO> storeTemplateStateSearch;
|
private SearchBuilder<TemplateDataStoreVO> storeTemplateStateSearch;
|
||||||
private SearchBuilder<TemplateDataStoreVO> storeTemplateDownloadStatusSearch;
|
private SearchBuilder<TemplateDataStoreVO> storeTemplateDownloadStatusSearch;
|
||||||
private SearchBuilder<TemplateDataStoreVO> storeTemplateSearch;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||||
@ -57,12 +59,24 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase<TemplateDataStoreVO
|
|||||||
storeSearch.and("destroyed", storeSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
|
storeSearch.and("destroyed", storeSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
|
||||||
storeSearch.done();
|
storeSearch.done();
|
||||||
|
|
||||||
|
templateSearch = createSearchBuilder();
|
||||||
|
templateSearch.and("template_id", templateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ);
|
||||||
|
templateSearch.and("destroyed", templateSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
|
||||||
|
templateSearch.done();
|
||||||
|
|
||||||
|
|
||||||
updateStateSearch = this.createSearchBuilder();
|
updateStateSearch = this.createSearchBuilder();
|
||||||
updateStateSearch.and("id", updateStateSearch.entity().getId(), Op.EQ);
|
updateStateSearch.and("id", updateStateSearch.entity().getId(), Op.EQ);
|
||||||
updateStateSearch.and("state", updateStateSearch.entity().getState(), Op.EQ);
|
updateStateSearch.and("state", updateStateSearch.entity().getState(), Op.EQ);
|
||||||
updateStateSearch.and("updatedCount", updateStateSearch.entity().getUpdatedCount(), Op.EQ);
|
updateStateSearch.and("updatedCount", updateStateSearch.entity().getUpdatedCount(), Op.EQ);
|
||||||
updateStateSearch.done();
|
updateStateSearch.done();
|
||||||
|
|
||||||
|
storeTemplateSearch = createSearchBuilder();
|
||||||
|
storeTemplateSearch.and("template_id", storeTemplateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ);
|
||||||
|
storeTemplateSearch.and("store_id", storeTemplateSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
|
||||||
|
storeTemplateSearch.and("destroyed", storeTemplateSearch.entity().getDestroyed(), SearchCriteria.Op.EQ);
|
||||||
|
storeTemplateSearch.done();
|
||||||
|
|
||||||
storeTemplateStateSearch = createSearchBuilder();
|
storeTemplateStateSearch = createSearchBuilder();
|
||||||
storeTemplateStateSearch.and("template_id", storeTemplateStateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ);
|
storeTemplateStateSearch.and("template_id", storeTemplateStateSearch.entity().getTemplateId(), SearchCriteria.Op.EQ);
|
||||||
storeTemplateStateSearch.and("store_id", storeTemplateStateSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
|
storeTemplateStateSearch.and("store_id", storeTemplateStateSearch.entity().getDataStoreId(), SearchCriteria.Op.EQ);
|
||||||
@ -133,6 +147,14 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase<TemplateDataStoreVO
|
|||||||
return listIncludingRemovedBy(sc);
|
return listIncludingRemovedBy(sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TemplateDataStoreVO> listDestroyed(long id) {
|
||||||
|
SearchCriteria<TemplateDataStoreVO> sc = storeSearch.create();
|
||||||
|
sc.setParameters("store_id", id);
|
||||||
|
sc.setParameters("destroyed", true);
|
||||||
|
return listIncludingRemovedBy(sc);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deletePrimaryRecordsForStore(long id) {
|
public void deletePrimaryRecordsForStore(long id) {
|
||||||
SearchCriteria<TemplateDataStoreVO> sc = storeSearch.create();
|
SearchCriteria<TemplateDataStoreVO> sc = storeSearch.create();
|
||||||
@ -144,12 +166,22 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase<TemplateDataStoreVO
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TemplateDataStoreVO> listByTemplateStore(long templateId, long storeId) {
|
||||||
|
SearchCriteria<TemplateDataStoreVO> sc = storeTemplateSearch.create();
|
||||||
|
sc.setParameters("template_id", templateId);
|
||||||
|
sc.setParameters("store_id", storeId);
|
||||||
|
sc.setParameters("destroyed", false);
|
||||||
|
return search(sc, null);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<TemplateDataStoreVO> listByTemplateStoreStatus(long templateId, long storeId, State... states) {
|
public List<TemplateDataStoreVO> listByTemplateStoreStatus(long templateId, long storeId, State... states) {
|
||||||
SearchCriteria<TemplateDataStoreVO> sc = storeTemplateStateSearch.create();
|
SearchCriteria<TemplateDataStoreVO> sc = storeTemplateStateSearch.create();
|
||||||
sc.setParameters("template_id", templateId);
|
sc.setParameters("template_id", templateId);
|
||||||
sc.setParameters("store_id", storeId);
|
sc.setParameters("store_id", storeId);
|
||||||
sc.setParameters("states", (Object[])states);
|
sc.setParameters("states", (Object[])states);
|
||||||
|
sc.setParameters("destroyed", false);
|
||||||
return search(sc, null);
|
return search(sc, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,10 +189,11 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase<TemplateDataStoreVO
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<TemplateDataStoreVO> listByTemplateStoreDownloadStatus(long templateId, long storeId, Status... status) {
|
public List<TemplateDataStoreVO> listByTemplateStoreDownloadStatus(long templateId, long storeId, Status... status) {
|
||||||
SearchCriteria<TemplateDataStoreVO> sc = storeTemplateStateSearch.create();
|
SearchCriteria<TemplateDataStoreVO> sc = storeTemplateDownloadStatusSearch.create();
|
||||||
sc.setParameters("template_id", templateId);
|
sc.setParameters("template_id", templateId);
|
||||||
sc.setParameters("store_id", storeId);
|
sc.setParameters("store_id", storeId);
|
||||||
sc.setParameters("downloadState", (Object[])status);
|
sc.setParameters("downloadState", (Object[])status);
|
||||||
|
sc.setParameters("destroyed", false);
|
||||||
return search(sc, null);
|
return search(sc, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,6 +206,22 @@ public class TemplateDataStoreDaoImpl extends GenericDaoBase<TemplateDataStoreVO
|
|||||||
return findOneIncludingRemovedBy(sc);
|
return findOneIncludingRemovedBy(sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TemplateDataStoreVO findByTemplate(long templateId) {
|
||||||
|
SearchCriteria<TemplateDataStoreVO> sc = templateSearch.create();
|
||||||
|
sc.setParameters("template_id", templateId);
|
||||||
|
sc.setParameters("destroyed", false);
|
||||||
|
return findOneIncludingRemovedBy(sc);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<TemplateDataStoreVO> listByTemplate(long templateId) {
|
||||||
|
SearchCriteria<TemplateDataStoreVO> sc = templateSearch.create();
|
||||||
|
sc.setParameters("template_id", templateId);
|
||||||
|
sc.setParameters("destroyed", false);
|
||||||
|
return search(sc, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -34,6 +34,8 @@ import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
|
|||||||
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
|
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
|
||||||
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
|
import org.apache.cloudstack.framework.async.AsyncCompletionCallback;
|
||||||
import org.apache.cloudstack.framework.async.AsyncRpcConext;
|
import org.apache.cloudstack.framework.async.AsyncRpcConext;
|
||||||
|
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.ImageStoreDriver;
|
||||||
import org.apache.cloudstack.storage.image.store.ImageStoreImpl;
|
import org.apache.cloudstack.storage.image.store.ImageStoreImpl;
|
||||||
import org.apache.cloudstack.storage.image.store.TemplateObject;
|
import org.apache.cloudstack.storage.image.store.TemplateObject;
|
||||||
@ -44,17 +46,23 @@ import org.apache.log4j.Logger;
|
|||||||
import com.cloud.agent.AgentManager;
|
import com.cloud.agent.AgentManager;
|
||||||
import com.cloud.agent.api.Answer;
|
import com.cloud.agent.api.Answer;
|
||||||
import com.cloud.agent.api.DeleteSnapshotBackupCommand;
|
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.storage.DeleteVolumeCommand;
|
||||||
import com.cloud.agent.api.to.DataStoreTO;
|
import com.cloud.agent.api.to.DataStoreTO;
|
||||||
import com.cloud.agent.api.to.NfsTO;
|
import com.cloud.agent.api.to.NfsTO;
|
||||||
import com.cloud.agent.api.to.S3TO;
|
import com.cloud.agent.api.to.S3TO;
|
||||||
import com.cloud.agent.api.to.SwiftTO;
|
import com.cloud.agent.api.to.SwiftTO;
|
||||||
|
import com.cloud.configuration.Resource.ResourceType;
|
||||||
|
import com.cloud.event.EventTypes;
|
||||||
|
import com.cloud.event.UsageEventUtils;
|
||||||
import com.cloud.host.HostVO;
|
import com.cloud.host.HostVO;
|
||||||
import com.cloud.host.dao.HostDao;
|
import com.cloud.host.dao.HostDao;
|
||||||
import com.cloud.storage.DataStoreRole;
|
import com.cloud.storage.DataStoreRole;
|
||||||
import com.cloud.storage.RegisterVolumePayload;
|
import com.cloud.storage.RegisterVolumePayload;
|
||||||
import com.cloud.storage.Storage.ImageFormat;
|
import com.cloud.storage.Storage.ImageFormat;
|
||||||
|
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
|
||||||
import com.cloud.storage.SnapshotVO;
|
import com.cloud.storage.SnapshotVO;
|
||||||
|
import com.cloud.storage.VMTemplateHostVO;
|
||||||
import com.cloud.storage.VMTemplateStorageResourceAssoc;
|
import com.cloud.storage.VMTemplateStorageResourceAssoc;
|
||||||
import com.cloud.storage.VMTemplateVO;
|
import com.cloud.storage.VMTemplateVO;
|
||||||
import com.cloud.storage.VMTemplateZoneVO;
|
import com.cloud.storage.VMTemplateZoneVO;
|
||||||
@ -68,9 +76,14 @@ import com.cloud.storage.dao.VolumeDao;
|
|||||||
import com.cloud.storage.dao.VolumeHostDao;
|
import com.cloud.storage.dao.VolumeHostDao;
|
||||||
import com.cloud.storage.download.DownloadMonitor;
|
import com.cloud.storage.download.DownloadMonitor;
|
||||||
import com.cloud.storage.s3.S3Manager;
|
import com.cloud.storage.s3.S3Manager;
|
||||||
|
import com.cloud.storage.secondary.SecondaryStorageVmManager;
|
||||||
import com.cloud.storage.snapshot.SnapshotManager;
|
import com.cloud.storage.snapshot.SnapshotManager;
|
||||||
import com.cloud.storage.swift.SwiftManager;
|
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.utils.exception.CloudRuntimeException;
|
||||||
|
import com.cloud.vm.UserVmVO;
|
||||||
|
import com.cloud.vm.dao.UserVmDao;
|
||||||
|
|
||||||
public class CloudStackImageStoreDriverImpl implements ImageStoreDriver {
|
public class CloudStackImageStoreDriverImpl implements ImageStoreDriver {
|
||||||
private static final Logger s_logger = Logger
|
private static final Logger s_logger = Logger
|
||||||
@ -92,6 +105,15 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver {
|
|||||||
private SwiftManager _swiftMgr;
|
private SwiftManager _swiftMgr;
|
||||||
@Inject
|
@Inject
|
||||||
private S3Manager _s3Mgr;
|
private S3Manager _s3Mgr;
|
||||||
|
@Inject AccountDao _accountDao;
|
||||||
|
@Inject UserVmDao _userVmDao;
|
||||||
|
@Inject
|
||||||
|
SecondaryStorageVmManager _ssvmMgr;
|
||||||
|
@Inject
|
||||||
|
private AgentManager _agentMgr;
|
||||||
|
@Inject TemplateDataStoreDao _templateStoreDao;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String grantAccess(DataObject data, EndPoint ep) {
|
public String grantAccess(DataObject data, EndPoint ep) {
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
@ -189,6 +211,60 @@ public class CloudStackImageStoreDriverImpl implements ImageStoreDriver {
|
|||||||
|
|
||||||
private void deleteTemplate(DataObject data, AsyncCompletionCallback<CommandResult> callback) {
|
private void deleteTemplate(DataObject data, AsyncCompletionCallback<CommandResult> 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<UserVmVO> userVmUsingIso = _userVmDao.listByIsoId(templateId);
|
||||||
|
// check if there is any VM using this ISO.
|
||||||
|
if (userVmUsingIso == null || userVmUsingIso.isEmpty()) {
|
||||||
|
HostVO ssAhost = _ssvmMgr.pickSsvmHost(store);
|
||||||
|
// 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(ssAhost, 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);
|
||||||
|
}
|
||||||
|
|
||||||
|
VMTemplateZoneVO templateZone = templateZoneDao.findByZoneTemplate(sZoneId, templateId);
|
||||||
|
|
||||||
|
if (templateZone != null) {
|
||||||
|
templateZoneDao.remove(templateZone.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void deleteSnapshot(DataObject data, AsyncCompletionCallback<CommandResult> callback) {
|
private void deleteSnapshot(DataObject data, AsyncCompletionCallback<CommandResult> callback) {
|
||||||
|
|||||||
@ -1234,69 +1234,80 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
public void cleanupSecondaryStorage(boolean recurring) {
|
public void cleanupSecondaryStorage(boolean recurring) {
|
||||||
try {
|
try {
|
||||||
// Cleanup templates in secondary storage hosts
|
// Cleanup templates in secondary storage hosts
|
||||||
List<HostVO> secondaryStorageHosts = _ssvmMgr
|
List<DataStore> imageStores = this.dataStoreMgr.getImageStoresByScope(new ZoneScope(null));
|
||||||
.listSecondaryStorageHostsInAllZones();
|
for (DataStore store : imageStores) {
|
||||||
for (HostVO secondaryStorageHost : secondaryStorageHosts) {
|
|
||||||
try {
|
try {
|
||||||
long hostId = secondaryStorageHost.getId();
|
long storeId = store.getId();
|
||||||
List<VMTemplateHostVO> destroyedTemplateHostVOs = _vmTemplateHostDao
|
List<TemplateDataStoreVO> destroyedTemplateStoreVOs = this._templateStoreDao.listDestroyed(storeId);
|
||||||
.listDestroyed(hostId);
|
|
||||||
s_logger.debug("Secondary storage garbage collector found "
|
s_logger.debug("Secondary storage garbage collector found "
|
||||||
+ destroyedTemplateHostVOs.size()
|
+ destroyedTemplateStoreVOs.size()
|
||||||
+ " templates to cleanup on secondary storage host: "
|
+ " templates to cleanup on secondary storage host: "
|
||||||
+ secondaryStorageHost.getName());
|
+ store.getName());
|
||||||
for (VMTemplateHostVO destroyedTemplateHostVO : destroyedTemplateHostVOs) {
|
for (TemplateDataStoreVO destroyedTemplateStoreVO : destroyedTemplateStoreVOs) {
|
||||||
if (!_tmpltMgr
|
if (!_tmpltMgr
|
||||||
.templateIsDeleteable(destroyedTemplateHostVO)) {
|
.templateIsDeleteable(destroyedTemplateStoreVO)) {
|
||||||
if (s_logger.isDebugEnabled()) {
|
if (s_logger.isDebugEnabled()) {
|
||||||
s_logger.debug("Not deleting template at: "
|
s_logger.debug("Not deleting template at: "
|
||||||
+ destroyedTemplateHostVO);
|
+ destroyedTemplateStoreVO);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s_logger.isDebugEnabled()) {
|
if (s_logger.isDebugEnabled()) {
|
||||||
s_logger.debug("Deleting template host: "
|
s_logger.debug("Deleting template store: "
|
||||||
+ destroyedTemplateHostVO);
|
+ destroyedTemplateStoreVO);
|
||||||
}
|
}
|
||||||
|
|
||||||
String installPath = destroyedTemplateHostVO
|
VMTemplateVO destroyedTemplate = this._vmTemplateDao.findById(destroyedTemplateStoreVO.getTemplateId());
|
||||||
|
if ( destroyedTemplate == null ){
|
||||||
|
s_logger.error("Cannot find template : " + destroyedTemplateStoreVO.getTemplateId() + " from template table");
|
||||||
|
throw new CloudRuntimeException("Template " + destroyedTemplateStoreVO.getTemplateId() + " is found in secondary storage, but not found in template table");
|
||||||
|
}
|
||||||
|
String installPath = destroyedTemplateStoreVO
|
||||||
.getInstallPath();
|
.getInstallPath();
|
||||||
|
|
||||||
|
HostVO ssAhost = this._ssvmMgr.pickSsvmHost(store);
|
||||||
if (installPath != null) {
|
if (installPath != null) {
|
||||||
|
|
||||||
Answer answer = _agentMgr.sendToSecStorage(
|
Answer answer = _agentMgr.sendToSecStorage(
|
||||||
secondaryStorageHost,
|
ssAhost,
|
||||||
new DeleteTemplateCommand(
|
new DeleteTemplateCommand(
|
||||||
secondaryStorageHost
|
store.getTO(),
|
||||||
.getStorageUrl(),
|
store.getUri(),
|
||||||
destroyedTemplateHostVO
|
destroyedTemplateStoreVO
|
||||||
.getInstallPath()));
|
.getInstallPath(),
|
||||||
|
destroyedTemplate.getId(),
|
||||||
|
destroyedTemplate.getAccountId()
|
||||||
|
|
||||||
|
));
|
||||||
|
|
||||||
if (answer == null || !answer.getResult()) {
|
if (answer == null || !answer.getResult()) {
|
||||||
s_logger.debug("Failed to delete "
|
s_logger.debug("Failed to delete "
|
||||||
+ destroyedTemplateHostVO
|
+ destroyedTemplateStoreVO
|
||||||
+ " due to "
|
+ " due to "
|
||||||
+ ((answer == null) ? "answer is null"
|
+ ((answer == null) ? "answer is null"
|
||||||
: answer.getDetails()));
|
: answer.getDetails()));
|
||||||
} else {
|
} else {
|
||||||
_vmTemplateHostDao
|
_vmTemplateHostDao
|
||||||
.remove(destroyedTemplateHostVO.getId());
|
.remove(destroyedTemplateStoreVO.getId());
|
||||||
s_logger.debug("Deleted template at: "
|
s_logger.debug("Deleted template at: "
|
||||||
+ destroyedTemplateHostVO
|
+ destroyedTemplateStoreVO
|
||||||
.getInstallPath());
|
.getInstallPath());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_vmTemplateHostDao.remove(destroyedTemplateHostVO
|
_vmTemplateHostDao.remove(destroyedTemplateStoreVO
|
||||||
.getId());
|
.getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
s_logger.warn(
|
s_logger.warn(
|
||||||
"problem cleaning up templates in secondary storage "
|
"problem cleaning up templates in secondary storage store "
|
||||||
+ secondaryStorageHost, e);
|
+ store.getName(), e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
List<HostVO> secondaryStorageHosts = _ssvmMgr
|
||||||
|
.listSecondaryStorageHostsInAllZones();
|
||||||
// Cleanup snapshot in secondary storage hosts
|
// Cleanup snapshot in secondary storage hosts
|
||||||
for (HostVO secondaryStorageHost : secondaryStorageHosts) {
|
for (HostVO secondaryStorageHost : secondaryStorageHosts) {
|
||||||
try {
|
try {
|
||||||
@ -2037,16 +2048,16 @@ public class StorageManagerImpl extends ManagerBase implements StorageManager, C
|
|||||||
if (scope != null) {
|
if (scope != null) {
|
||||||
try {
|
try {
|
||||||
scopeType = Enum.valueOf(ScopeType.class, scope.toUpperCase());
|
scopeType = Enum.valueOf(ScopeType.class, scope.toUpperCase());
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new InvalidParameterValueException("invalid scope" + scope);
|
throw new InvalidParameterValueException("invalid scope" + scope);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scopeType != ScopeType.ZONE) {
|
if (scopeType != ScopeType.ZONE) {
|
||||||
throw new InvalidParameterValueException("Only zone wide cache storage is supported");
|
throw new InvalidParameterValueException("Only zone wide cache storage is supported");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scopeType == ScopeType.ZONE && dcId == null) {
|
if (scopeType == ScopeType.ZONE && dcId == null) {
|
||||||
throw new InvalidParameterValueException("zone id can't be null, if scope is zone");
|
throw new InvalidParameterValueException("zone id can't be null, if scope is zone");
|
||||||
}
|
}
|
||||||
|
|||||||
@ -38,6 +38,7 @@ import org.apache.cloudstack.engine.subsystem.api.storage.ImageDataFactory;
|
|||||||
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
|
import org.apache.cloudstack.engine.subsystem.api.storage.TemplateService;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
|
import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
|
||||||
import org.apache.cloudstack.framework.async.AsyncCallFuture;
|
import org.apache.cloudstack.framework.async.AsyncCallFuture;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import com.cloud.agent.AgentManager;
|
import com.cloud.agent.AgentManager;
|
||||||
@ -180,7 +181,7 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase implements Te
|
|||||||
}
|
}
|
||||||
for (DataStore imageStore : imageStores) {
|
for (DataStore imageStore : imageStores) {
|
||||||
AsyncCallFuture<CommandResult> future = this.imageService
|
AsyncCallFuture<CommandResult> future = this.imageService
|
||||||
.createTemplateAsync(this.imageFactory.getTemplate(template.getId()), imageStore);
|
.createTemplateAsync(this.imageFactory.getTemplate(template.getId(), imageStore), imageStore);
|
||||||
try {
|
try {
|
||||||
future.get();
|
future.get();
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
@ -202,123 +203,60 @@ public class HypervisorTemplateAdapter extends TemplateAdapterBase implements Te
|
|||||||
boolean success = true;
|
boolean success = true;
|
||||||
|
|
||||||
VMTemplateVO template = (VMTemplateVO)profile.getTemplate();
|
VMTemplateVO template = (VMTemplateVO)profile.getTemplate();
|
||||||
Long zoneId = profile.getZoneId();
|
|
||||||
Long templateId = template.getId();
|
|
||||||
|
|
||||||
String zoneName;
|
// find all eligible image stores for this template
|
||||||
List<HostVO> secondaryStorageHosts;
|
List<DataStore> imageStores = this.templateMgr.getImageStoreByTemplate(template.getId(), profile.getZoneId());
|
||||||
if (!template.isCrossZones() && zoneId != null) {
|
if ( imageStores == null || imageStores.size() == 0 ){
|
||||||
DataCenterVO zone = _dcDao.findById(zoneId);
|
throw new CloudRuntimeException("Unable to find image store to delete template "+ profile.getTemplate());
|
||||||
zoneName = zone.getName();
|
}
|
||||||
secondaryStorageHosts = _ssvmMgr.listSecondaryStorageHostsInOneZone(zoneId);
|
|
||||||
} else {
|
|
||||||
zoneName = "(all zones)";
|
|
||||||
secondaryStorageHosts = _ssvmMgr.listSecondaryStorageHostsInAllZones();
|
|
||||||
}
|
|
||||||
|
|
||||||
s_logger.debug("Attempting to mark template host refs for template: " + template.getName() + " as destroyed in zone: " + zoneName);
|
// Make sure the template is downloaded to all found image stores
|
||||||
|
for (DataStore store : imageStores) {
|
||||||
|
long storeId = store.getId();
|
||||||
|
List<TemplateDataStoreVO> templateStores = _tmpltStoreDao.listByTemplateStore(template.getId(), storeId);
|
||||||
|
for (TemplateDataStoreVO templateStore : templateStores) {
|
||||||
|
if (templateStore.getDownloadState() == Status.DOWNLOAD_IN_PROGRESS) {
|
||||||
|
String errorMsg = "Please specify a template that is not currently being downloaded.";
|
||||||
|
s_logger.debug("Template: " + template.getName() + " is currently being downloaded to secondary storage host: " + store.getName() + "; cant' delete it.");
|
||||||
|
throw new CloudRuntimeException(errorMsg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure the template is downloaded to all the necessary secondary storage hosts
|
|
||||||
for (HostVO secondaryStorageHost : secondaryStorageHosts) {
|
|
||||||
long hostId = secondaryStorageHost.getId();
|
|
||||||
List<VMTemplateHostVO> templateHostVOs = _tmpltHostDao.listByHostTemplate(hostId, templateId);
|
|
||||||
for (VMTemplateHostVO templateHostVO : templateHostVOs) {
|
|
||||||
if (templateHostVO.getDownloadState() == Status.DOWNLOAD_IN_PROGRESS) {
|
|
||||||
String errorMsg = "Please specify a template that is not currently being downloaded.";
|
|
||||||
s_logger.debug("Template: " + template.getName() + " is currently being downloaded to secondary storage host: " + secondaryStorageHost.getName() + "; cant' delete it.");
|
|
||||||
throw new CloudRuntimeException(errorMsg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Account account = _accountDao.findByIdIncludingRemoved(template.getAccountId());
|
for (DataStore imageStore : imageStores) {
|
||||||
String eventType = "";
|
s_logger.info("Delete template from image store: " + imageStore.getName());
|
||||||
|
AsyncCallFuture<CommandResult> future = this.imageService
|
||||||
|
.deleteTemplateAsync(this.imageFactory.getTemplate(template.getId(), imageStore));
|
||||||
|
try {
|
||||||
|
CommandResult result = future.get();
|
||||||
|
success = result.isSuccess();
|
||||||
|
if ( !success )
|
||||||
|
break;
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
s_logger.debug("delete template Failed", e);
|
||||||
|
throw new CloudRuntimeException("delete template Failed", e);
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
s_logger.debug("delete template Failed", e);
|
||||||
|
throw new CloudRuntimeException("delete template Failed", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (template.getFormat().equals(ImageFormat.ISO)){
|
if (success) {
|
||||||
eventType = EventTypes.EVENT_ISO_DELETE;
|
s_logger.info("Delete template from template table");
|
||||||
} else {
|
// remove template from vm_templates table
|
||||||
eventType = EventTypes.EVENT_TEMPLATE_DELETE;
|
if (_tmpltDao.remove(template.getId())) {
|
||||||
}
|
// Decrement the number of templates and total secondary storage
|
||||||
|
// space used by the account
|
||||||
|
Account account = _accountDao.findByIdIncludingRemoved(template.getAccountId());
|
||||||
|
_resourceLimitMgr.decrementResourceCount(template.getAccountId(), ResourceType.template);
|
||||||
|
_resourceLimitMgr.recalculateResourceCount(template.getAccountId(), account.getDomainId(),
|
||||||
|
ResourceType.secondary_storage.getOrdinal());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
|
||||||
// Iterate through all necessary secondary storage hosts and mark the template on each host as destroyed
|
|
||||||
for (HostVO secondaryStorageHost : secondaryStorageHosts) {
|
|
||||||
long hostId = secondaryStorageHost.getId();
|
|
||||||
long sZoneId = secondaryStorageHost.getDataCenterId();
|
|
||||||
List<VMTemplateHostVO> templateHostVOs = _tmpltHostDao.listByHostTemplate(hostId, templateId);
|
|
||||||
for (VMTemplateHostVO templateHostVO : templateHostVOs) {
|
|
||||||
VMTemplateHostVO lock = _tmpltHostDao.acquireInLockTable(templateHostVO.getId());
|
|
||||||
try {
|
|
||||||
if (lock == null) {
|
|
||||||
s_logger.debug("Failed to acquire lock when deleting templateHostVO with ID: " + templateHostVO.getId());
|
|
||||||
success = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
UsageEventUtils.publishUsageEvent(eventType, account.getId(), sZoneId, templateId, null, null, null);
|
|
||||||
templateHostVO.setDestroyed(true);
|
|
||||||
_tmpltHostDao.update(templateHostVO.getId(), templateHostVO);
|
|
||||||
String installPath = templateHostVO.getInstallPath();
|
|
||||||
List<UserVmVO> userVmUsingIso = _userVmDao.listByIsoId(templateId);
|
|
||||||
//check if there is any VM using this ISO.
|
|
||||||
if (userVmUsingIso == null || userVmUsingIso.isEmpty()) {
|
|
||||||
if (installPath != null) {
|
|
||||||
Answer answer = _agentMgr.sendToSecStorage(secondaryStorageHost, new DeleteTemplateCommand(secondaryStorageHost.getStorageUrl(), installPath));
|
|
||||||
|
|
||||||
if (answer == null || !answer.getResult()) {
|
|
||||||
s_logger.debug("Failed to delete " + templateHostVO + " due to " + ((answer == null) ? "answer is null" : answer.getDetails()));
|
|
||||||
} else {
|
|
||||||
_tmpltHostDao.remove(templateHostVO.getId());
|
|
||||||
s_logger.debug("Deleted template at: " + installPath);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
_tmpltHostDao.remove(templateHostVO.getId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
VMTemplateZoneVO templateZone = _tmpltZoneDao.findByZoneTemplate(sZoneId, templateId);
|
|
||||||
|
|
||||||
if (templateZone != null) {
|
|
||||||
_tmpltZoneDao.remove(templateZone.getId());
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
if (lock != null) {
|
|
||||||
_tmpltHostDao.releaseFromLockTable(lock.getId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!success) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
s_logger.debug("Successfully marked template host refs for template: " + template.getName() + " as destroyed in zone: " + zoneName);
|
|
||||||
|
|
||||||
// If there are no more non-destroyed template host entries for this template, delete it
|
|
||||||
if (success && (_tmpltHostDao.listByTemplateId(templateId).size() == 0)) {
|
|
||||||
long accountId = template.getAccountId();
|
|
||||||
|
|
||||||
VMTemplateVO lock = _tmpltDao.acquireInLockTable(templateId);
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (lock == null) {
|
|
||||||
s_logger.debug("Failed to acquire lock when deleting template with ID: " + templateId);
|
|
||||||
success = false;
|
|
||||||
} else if (_tmpltDao.remove(templateId)) {
|
|
||||||
// Decrement the number of templates and total secondary storage space used by the account
|
|
||||||
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.template);
|
|
||||||
_resourceLimitMgr.recalculateResourceCount(accountId, account.getDomainId(),
|
|
||||||
ResourceType.secondary_storage.getOrdinal());
|
|
||||||
}
|
|
||||||
|
|
||||||
} finally {
|
|
||||||
if (lock != null) {
|
|
||||||
_tmpltDao.releaseFromLockTable(lock.getId());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
s_logger.debug("Removed template: " + template.getName() + " because all of its template host refs were marked as destroyed.");
|
|
||||||
}
|
|
||||||
|
|
||||||
return success;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public TemplateProfile prepareDelete(DeleteTemplateCmd cmd) {
|
public TemplateProfile prepareDelete(DeleteTemplateCmd cmd) {
|
||||||
|
|||||||
@ -28,6 +28,7 @@ import org.apache.cloudstack.api.command.user.template.DeleteTemplateCmd;
|
|||||||
import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd;
|
import org.apache.cloudstack.api.command.user.template.RegisterTemplateCmd;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStoreManager;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
|
|
||||||
import com.cloud.api.ApiDBUtils;
|
import com.cloud.api.ApiDBUtils;
|
||||||
@ -75,6 +76,7 @@ public abstract class TemplateAdapterBase extends AdapterBase implements Templat
|
|||||||
protected @Inject DataCenterDao _dcDao;
|
protected @Inject DataCenterDao _dcDao;
|
||||||
protected @Inject VMTemplateDao _tmpltDao;
|
protected @Inject VMTemplateDao _tmpltDao;
|
||||||
protected @Inject VMTemplateHostDao _tmpltHostDao;
|
protected @Inject VMTemplateHostDao _tmpltHostDao;
|
||||||
|
protected @Inject TemplateDataStoreDao _tmpltStoreDao;
|
||||||
protected @Inject VMTemplateZoneDao _tmpltZoneDao;
|
protected @Inject VMTemplateZoneDao _tmpltZoneDao;
|
||||||
protected @Inject UsageEventDao _usageEventDao;
|
protected @Inject UsageEventDao _usageEventDao;
|
||||||
protected @Inject HostDao _hostDao;
|
protected @Inject HostDao _hostDao;
|
||||||
|
|||||||
@ -20,6 +20,7 @@ import java.util.List;
|
|||||||
|
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
import org.apache.cloudstack.engine.subsystem.api.storage.DataStore;
|
||||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
|
||||||
|
|
||||||
import com.cloud.dc.DataCenterVO;
|
import com.cloud.dc.DataCenterVO;
|
||||||
import com.cloud.exception.InternalErrorException;
|
import com.cloud.exception.InternalErrorException;
|
||||||
@ -39,7 +40,7 @@ public interface TemplateManager extends TemplateApiService{
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Prepares a template for vm creation for a certain storage pool.
|
* Prepares a template for vm creation for a certain storage pool.
|
||||||
*
|
*
|
||||||
* @param template
|
* @param template
|
||||||
* template to prepare
|
* template to prepare
|
||||||
* @param pool
|
* @param pool
|
||||||
@ -52,7 +53,7 @@ public interface TemplateManager extends TemplateApiService{
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Copies a template from its current secondary storage server to the secondary storage server in the specified zone.
|
* Copies a template from its current secondary storage server to the secondary storage server in the specified zone.
|
||||||
*
|
*
|
||||||
* @param template
|
* @param template
|
||||||
* @param srcSecHost
|
* @param srcSecHost
|
||||||
* @param srcZone
|
* @param srcZone
|
||||||
@ -66,7 +67,7 @@ public interface TemplateManager extends TemplateApiService{
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes a template from secondary storage servers
|
* Deletes a template from secondary storage servers
|
||||||
*
|
*
|
||||||
* @param userId
|
* @param userId
|
||||||
* @param templateId
|
* @param templateId
|
||||||
* @param zoneId
|
* @param zoneId
|
||||||
@ -77,7 +78,7 @@ public interface TemplateManager extends TemplateApiService{
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Lists templates in the specified storage pool that are not being used by any VM.
|
* Lists templates in the specified storage pool that are not being used by any VM.
|
||||||
*
|
*
|
||||||
* @param pool
|
* @param pool
|
||||||
* @return list of VMTemplateStoragePoolVO
|
* @return list of VMTemplateStoragePoolVO
|
||||||
*/
|
*/
|
||||||
@ -85,13 +86,15 @@ public interface TemplateManager extends TemplateApiService{
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes a template in the specified storage pool.
|
* Deletes a template in the specified storage pool.
|
||||||
*
|
*
|
||||||
* @param templatePoolVO
|
* @param templatePoolVO
|
||||||
*/
|
*/
|
||||||
void evictTemplateFromStoragePool(VMTemplateStoragePoolVO templatePoolVO);
|
void evictTemplateFromStoragePool(VMTemplateStoragePoolVO templatePoolVO);
|
||||||
|
|
||||||
boolean templateIsDeleteable(VMTemplateHostVO templateHostRef);
|
boolean templateIsDeleteable(VMTemplateHostVO templateHostRef);
|
||||||
|
|
||||||
|
boolean templateIsDeleteable(TemplateDataStoreVO templateStoreRef);
|
||||||
|
|
||||||
VMTemplateHostVO prepareISOForCreate(VMTemplateVO template, StoragePool pool);
|
VMTemplateHostVO prepareISOForCreate(VMTemplateVO template, StoragePool pool);
|
||||||
|
|
||||||
|
|
||||||
@ -117,4 +120,6 @@ public interface TemplateManager extends TemplateApiService{
|
|||||||
|
|
||||||
String getChecksum(Long hostId, String templatePath);
|
String getChecksum(Long hostId, String templatePath);
|
||||||
|
|
||||||
|
List<DataStore> getImageStoreByTemplate(long templateId, Long zoneId);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -65,8 +65,12 @@ import org.apache.cloudstack.engine.subsystem.api.storage.VolumeDataFactory;
|
|||||||
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
|
import org.apache.cloudstack.engine.subsystem.api.storage.VolumeInfo;
|
||||||
import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
|
import org.apache.cloudstack.engine.subsystem.api.storage.ZoneScope;
|
||||||
import org.apache.cloudstack.framework.async.AsyncCallFuture;
|
import org.apache.cloudstack.framework.async.AsyncCallFuture;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ImageStoreDao;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.ImageStoreVO;
|
||||||
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
import org.apache.cloudstack.storage.datastore.db.PrimaryDataStoreDao;
|
||||||
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
import org.apache.cloudstack.storage.datastore.db.StoragePoolVO;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
|
||||||
|
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
|
||||||
import org.apache.log4j.Logger;
|
import org.apache.log4j.Logger;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@ -192,6 +196,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
private final static Logger s_logger = Logger.getLogger(TemplateManagerImpl.class);
|
private final static Logger s_logger = Logger.getLogger(TemplateManagerImpl.class);
|
||||||
@Inject VMTemplateDao _tmpltDao;
|
@Inject VMTemplateDao _tmpltDao;
|
||||||
@Inject VMTemplateHostDao _tmpltHostDao;
|
@Inject VMTemplateHostDao _tmpltHostDao;
|
||||||
|
@Inject TemplateDataStoreDao _tmplStoreDao;
|
||||||
@Inject VMTemplatePoolDao _tmpltPoolDao;
|
@Inject VMTemplatePoolDao _tmpltPoolDao;
|
||||||
@Inject VMTemplateZoneDao _tmpltZoneDao;
|
@Inject VMTemplateZoneDao _tmpltZoneDao;
|
||||||
@Inject
|
@Inject
|
||||||
@ -253,21 +258,22 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
protected ResourceManager _resourceMgr;
|
protected ResourceManager _resourceMgr;
|
||||||
@Inject VolumeManager volumeMgr;
|
@Inject VolumeManager volumeMgr;
|
||||||
@Inject VMTemplateHostDao templateHostDao;
|
@Inject VMTemplateHostDao templateHostDao;
|
||||||
|
@Inject ImageStoreDao _imageStoreDao;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int _primaryStorageDownloadWait;
|
int _primaryStorageDownloadWait;
|
||||||
protected SearchBuilder<VMTemplateHostVO> HostTemplateStatesSearch;
|
protected SearchBuilder<VMTemplateHostVO> HostTemplateStatesSearch;
|
||||||
|
|
||||||
int _storagePoolMaxWaitSeconds = 3600;
|
int _storagePoolMaxWaitSeconds = 3600;
|
||||||
boolean _disableExtraction = false;
|
boolean _disableExtraction = false;
|
||||||
ExecutorService _preloadExecutor;
|
ExecutorService _preloadExecutor;
|
||||||
ScheduledExecutorService _swiftTemplateSyncExecutor;
|
ScheduledExecutorService _swiftTemplateSyncExecutor;
|
||||||
|
|
||||||
private ScheduledExecutorService _s3TemplateSyncExecutor = null;
|
private ScheduledExecutorService _s3TemplateSyncExecutor = null;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
protected List<TemplateAdapter> _adapters;
|
protected List<TemplateAdapter> _adapters;
|
||||||
|
|
||||||
private TemplateAdapter getAdapter(HypervisorType type) {
|
private TemplateAdapter getAdapter(HypervisorType type) {
|
||||||
TemplateAdapter adapter = null;
|
TemplateAdapter adapter = null;
|
||||||
if (type == HypervisorType.BareMetal) {
|
if (type == HypervisorType.BareMetal) {
|
||||||
@ -276,21 +282,21 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
// see HyervisorTemplateAdapter
|
// see HyervisorTemplateAdapter
|
||||||
adapter = AdapterBase.getAdapterByName(_adapters, TemplateAdapterType.Hypervisor.getName());
|
adapter = AdapterBase.getAdapterByName(_adapters, TemplateAdapterType.Hypervisor.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (adapter == null) {
|
if (adapter == null) {
|
||||||
throw new CloudRuntimeException("Cannot find template adapter for " + type.toString());
|
throw new CloudRuntimeException("Cannot find template adapter for " + type.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
return adapter;
|
return adapter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ActionEvent(eventType = EventTypes.EVENT_ISO_CREATE, eventDescription = "creating iso")
|
@ActionEvent(eventType = EventTypes.EVENT_ISO_CREATE, eventDescription = "creating iso")
|
||||||
public VirtualMachineTemplate registerIso(RegisterIsoCmd cmd) throws ResourceAllocationException{
|
public VirtualMachineTemplate registerIso(RegisterIsoCmd cmd) throws ResourceAllocationException{
|
||||||
TemplateAdapter adapter = getAdapter(HypervisorType.None);
|
TemplateAdapter adapter = getAdapter(HypervisorType.None);
|
||||||
TemplateProfile profile = adapter.prepare(cmd);
|
TemplateProfile profile = adapter.prepare(cmd);
|
||||||
VMTemplateVO template = adapter.create(profile);
|
VMTemplateVO template = adapter.create(profile);
|
||||||
|
|
||||||
if (template != null){
|
if (template != null){
|
||||||
return template;
|
return template;
|
||||||
}else {
|
}else {
|
||||||
@ -307,18 +313,18 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
throw new PermissionDeniedException("Parameter templatetag can only be specified by a Root Admin, permission denied");
|
throw new PermissionDeniedException("Parameter templatetag can only be specified by a Root Admin, permission denied");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TemplateAdapter adapter = getAdapter(HypervisorType.getType(cmd.getHypervisor()));
|
TemplateAdapter adapter = getAdapter(HypervisorType.getType(cmd.getHypervisor()));
|
||||||
TemplateProfile profile = adapter.prepare(cmd);
|
TemplateProfile profile = adapter.prepare(cmd);
|
||||||
VMTemplateVO template = adapter.create(profile);
|
VMTemplateVO template = adapter.create(profile);
|
||||||
|
|
||||||
if (template != null){
|
if (template != null){
|
||||||
return template;
|
return template;
|
||||||
}else {
|
}else {
|
||||||
throw new CloudRuntimeException("Failed to create a template");
|
throw new CloudRuntimeException("Failed to create a template");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DataStore getImageStore(String storeUuid, Long zoneId) {
|
public DataStore getImageStore(String storeUuid, Long zoneId) {
|
||||||
DataStore imageStore = null;
|
DataStore imageStore = null;
|
||||||
@ -331,7 +337,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
}
|
}
|
||||||
imageStore = stores.get(0);
|
imageStore = stores.get(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return imageStore;
|
return imageStore;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -344,7 +350,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
String url = cmd.getUrl();
|
String url = cmd.getUrl();
|
||||||
String mode = cmd.getMode();
|
String mode = cmd.getMode();
|
||||||
Long eventId = cmd.getStartEventId();
|
Long eventId = cmd.getStartEventId();
|
||||||
|
|
||||||
// FIXME: async job needs fixing
|
// FIXME: async job needs fixing
|
||||||
Long uploadId = extract(account, templateId, url, zoneId, mode, eventId, true, null, _asyncMgr);
|
Long uploadId = extract(account, templateId, url, zoneId, mode, eventId, true, null, _asyncMgr);
|
||||||
if (uploadId != null){
|
if (uploadId != null){
|
||||||
@ -372,16 +378,16 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
throw new CloudRuntimeException("Failed to extract the teamplate");
|
throw new CloudRuntimeException("Failed to extract the teamplate");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VirtualMachineTemplate prepareTemplate(long templateId, long zoneId) {
|
public VirtualMachineTemplate prepareTemplate(long templateId, long zoneId) {
|
||||||
|
|
||||||
VMTemplateVO vmTemplate = _tmpltDao.findById(templateId);
|
VMTemplateVO vmTemplate = _tmpltDao.findById(templateId);
|
||||||
if(vmTemplate == null)
|
if(vmTemplate == null)
|
||||||
throw new InvalidParameterValueException("Unable to find template id=" + templateId);
|
throw new InvalidParameterValueException("Unable to find template id=" + templateId);
|
||||||
|
|
||||||
_accountMgr.checkAccess(UserContext.current().getCaller(), AccessType.ModifyEntry, true, vmTemplate);
|
_accountMgr.checkAccess(UserContext.current().getCaller(), AccessType.ModifyEntry, true, vmTemplate);
|
||||||
|
|
||||||
prepareTemplateInAllStoragePools(vmTemplate, zoneId);
|
prepareTemplateInAllStoragePools(vmTemplate, zoneId);
|
||||||
return vmTemplate;
|
return vmTemplate;
|
||||||
}
|
}
|
||||||
@ -392,22 +398,22 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
desc = Upload.Type.ISO.toString();
|
desc = Upload.Type.ISO.toString();
|
||||||
}
|
}
|
||||||
eventId = eventId == null ? 0:eventId;
|
eventId = eventId == null ? 0:eventId;
|
||||||
|
|
||||||
if (!_accountMgr.isRootAdmin(caller.getType()) && _disableExtraction) {
|
if (!_accountMgr.isRootAdmin(caller.getType()) && _disableExtraction) {
|
||||||
throw new PermissionDeniedException("Extraction has been disabled by admin");
|
throw new PermissionDeniedException("Extraction has been disabled by admin");
|
||||||
}
|
}
|
||||||
|
|
||||||
VMTemplateVO template = _tmpltDao.findById(templateId);
|
VMTemplateVO template = _tmpltDao.findById(templateId);
|
||||||
if (template == null || template.getRemoved() != null) {
|
if (template == null || template.getRemoved() != null) {
|
||||||
throw new InvalidParameterValueException("Unable to find " +desc+ " with id " + templateId);
|
throw new InvalidParameterValueException("Unable to find " +desc+ " with id " + templateId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (template.getTemplateType() == Storage.TemplateType.SYSTEM){
|
if (template.getTemplateType() == Storage.TemplateType.SYSTEM){
|
||||||
throw new InvalidParameterValueException("Unable to extract the " + desc + " " + template.getName() + " as it is a default System template");
|
throw new InvalidParameterValueException("Unable to extract the " + desc + " " + template.getName() + " as it is a default System template");
|
||||||
} else if (template.getTemplateType() == Storage.TemplateType.PERHOST){
|
} else if (template.getTemplateType() == Storage.TemplateType.PERHOST){
|
||||||
throw new InvalidParameterValueException("Unable to extract the " + desc + " " + template.getName() + " as it resides on host and not on SSVM");
|
throw new InvalidParameterValueException("Unable to extract the " + desc + " " + template.getName() + " as it resides on host and not on SSVM");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isISO) {
|
if (isISO) {
|
||||||
if (template.getFormat() != ImageFormat.ISO ){
|
if (template.getFormat() != ImageFormat.ISO ){
|
||||||
throw new InvalidParameterValueException("Unsupported format, could not extract the ISO");
|
throw new InvalidParameterValueException("Unsupported format, could not extract the ISO");
|
||||||
@ -417,7 +423,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
throw new InvalidParameterValueException("Unsupported format, could not extract the template");
|
throw new InvalidParameterValueException("Unsupported format, could not extract the template");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zoneId == null && _swiftMgr.isSwiftEnabled()) {
|
if (zoneId == null && _swiftMgr.isSwiftEnabled()) {
|
||||||
zoneId = _swiftMgr.chooseZoneForTmpltExtract(templateId);
|
zoneId = _swiftMgr.chooseZoneForTmpltExtract(templateId);
|
||||||
}
|
}
|
||||||
@ -429,13 +435,13 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
if (_dcDao.findById(zoneId) == null) {
|
if (_dcDao.findById(zoneId) == null) {
|
||||||
throw new IllegalArgumentException("Please specify a valid zone.");
|
throw new IllegalArgumentException("Please specify a valid zone.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_accountMgr.isRootAdmin(caller.getType()) && !template.isExtractable()) {
|
if (!_accountMgr.isRootAdmin(caller.getType()) && !template.isExtractable()) {
|
||||||
throw new InvalidParameterValueException("Unable to extract template id=" + templateId + " as it's not extractable");
|
throw new InvalidParameterValueException("Unable to extract template id=" + templateId + " as it's not extractable");
|
||||||
}
|
}
|
||||||
|
|
||||||
_accountMgr.checkAccess(caller, AccessType.ModifyEntry, true, template);
|
_accountMgr.checkAccess(caller, AccessType.ModifyEntry, true, template);
|
||||||
|
|
||||||
List<HostVO> sservers = getSecondaryStorageHosts(zoneId);
|
List<HostVO> sservers = getSecondaryStorageHosts(zoneId);
|
||||||
|
|
||||||
VMTemplateHostVO tmpltHostRef = null;
|
VMTemplateHostVO tmpltHostRef = null;
|
||||||
@ -452,7 +458,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tmpltHostRef == null && _swiftMgr.isSwiftEnabled()) {
|
if (tmpltHostRef == null && _swiftMgr.isSwiftEnabled()) {
|
||||||
SwiftTO swift = _swiftMgr.getSwiftTO(templateId);
|
SwiftTO swift = _swiftMgr.getSwiftTO(templateId);
|
||||||
if (swift != null && sservers != null) {
|
if (swift != null && sservers != null) {
|
||||||
@ -468,14 +474,14 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
if (tmpltHostRef == null) {
|
if (tmpltHostRef == null) {
|
||||||
throw new InvalidParameterValueException("The " + desc + " has not been downloaded ");
|
throw new InvalidParameterValueException("The " + desc + " has not been downloaded ");
|
||||||
}
|
}
|
||||||
|
|
||||||
Upload.Mode extractMode;
|
Upload.Mode extractMode;
|
||||||
if (mode == null || (!mode.equalsIgnoreCase(Upload.Mode.FTP_UPLOAD.toString()) && !mode.equalsIgnoreCase(Upload.Mode.HTTP_DOWNLOAD.toString())) ){
|
if (mode == null || (!mode.equalsIgnoreCase(Upload.Mode.FTP_UPLOAD.toString()) && !mode.equalsIgnoreCase(Upload.Mode.HTTP_DOWNLOAD.toString())) ){
|
||||||
throw new InvalidParameterValueException("Please specify a valid extract Mode. Supported modes: "+ Upload.Mode.FTP_UPLOAD + ", " + Upload.Mode.HTTP_DOWNLOAD);
|
throw new InvalidParameterValueException("Please specify a valid extract Mode. Supported modes: "+ Upload.Mode.FTP_UPLOAD + ", " + Upload.Mode.HTTP_DOWNLOAD);
|
||||||
} else {
|
} else {
|
||||||
extractMode = mode.equalsIgnoreCase(Upload.Mode.FTP_UPLOAD.toString()) ? Upload.Mode.FTP_UPLOAD : Upload.Mode.HTTP_DOWNLOAD;
|
extractMode = mode.equalsIgnoreCase(Upload.Mode.FTP_UPLOAD.toString()) ? Upload.Mode.FTP_UPLOAD : Upload.Mode.HTTP_DOWNLOAD;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (extractMode == Upload.Mode.FTP_UPLOAD){
|
if (extractMode == Upload.Mode.FTP_UPLOAD){
|
||||||
URI uri = null;
|
URI uri = null;
|
||||||
try {
|
try {
|
||||||
@ -486,7 +492,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
throw new InvalidParameterValueException("Invalid url given: " + url);
|
throw new InvalidParameterValueException("Invalid url given: " + url);
|
||||||
}
|
}
|
||||||
|
|
||||||
String host = uri.getHost();
|
String host = uri.getHost();
|
||||||
try {
|
try {
|
||||||
InetAddress hostAddr = InetAddress.getByName(host);
|
InetAddress hostAddr = InetAddress.getByName(host);
|
||||||
@ -499,22 +505,22 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
} catch (UnknownHostException uhe) {
|
} catch (UnknownHostException uhe) {
|
||||||
throw new InvalidParameterValueException("Unable to resolve " + host);
|
throw new InvalidParameterValueException("Unable to resolve " + host);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_uploadMonitor.isTypeUploadInProgress(templateId, isISO ? Type.ISO : Type.TEMPLATE) ){
|
if (_uploadMonitor.isTypeUploadInProgress(templateId, isISO ? Type.ISO : Type.TEMPLATE) ){
|
||||||
throw new IllegalArgumentException(template.getName() + " upload is in progress. Please wait for some time to schedule another upload for the same");
|
throw new IllegalArgumentException(template.getName() + " upload is in progress. Please wait for some time to schedule another upload for the same");
|
||||||
}
|
}
|
||||||
|
|
||||||
return _uploadMonitor.extractTemplate(template, url, tmpltHostRef, zoneId, eventId, job.getId(), mgr);
|
return _uploadMonitor.extractTemplate(template, url, tmpltHostRef, zoneId, eventId, job.getId(), mgr);
|
||||||
}
|
}
|
||||||
|
|
||||||
UploadVO vo = _uploadMonitor.createEntityDownloadURL(template, tmpltHostRef, zoneId, eventId);
|
UploadVO vo = _uploadMonitor.createEntityDownloadURL(template, tmpltHostRef, zoneId, eventId);
|
||||||
if (vo != null){
|
if (vo != null){
|
||||||
return vo.getId();
|
return vo.getId();
|
||||||
}else{
|
}else{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void prepareTemplateInAllStoragePools(final VMTemplateVO template, long zoneId) {
|
public void prepareTemplateInAllStoragePools(final VMTemplateVO template, long zoneId) {
|
||||||
List<StoragePoolVO> pools = _poolDao.listByStatus(StoragePoolStatus.Up);
|
List<StoragePoolVO> pools = _poolDao.listByStatus(StoragePoolStatus.Up);
|
||||||
for(final StoragePoolVO pool : pools) {
|
for(final StoragePoolVO pool : pools) {
|
||||||
@ -528,7 +534,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
s_logger.warn("Unexpected exception ", e);
|
s_logger.warn("Unexpected exception ", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void reallyRun() {
|
private void reallyRun() {
|
||||||
s_logger.info("Start to preload template " + template.getId() + " into primary storage " + pool.getId());
|
s_logger.info("Start to preload template " + template.getId() + " into primary storage " + pool.getId());
|
||||||
StoragePool pol = (StoragePool)dataStoreMgr.getPrimaryDataStore(pool.getId());
|
StoragePool pol = (StoragePool)dataStoreMgr.getPrimaryDataStore(pool.getId());
|
||||||
@ -541,7 +547,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String downloadTemplateFromSwiftToSecondaryStorage(long dcId, long templateId){
|
String downloadTemplateFromSwiftToSecondaryStorage(long dcId, long templateId){
|
||||||
VMTemplateVO template = _tmpltDao.findById(templateId);
|
VMTemplateVO template = _tmpltDao.findById(templateId);
|
||||||
if ( template == null ) {
|
if ( template == null ) {
|
||||||
@ -648,7 +654,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
@Override @DB
|
@Override @DB
|
||||||
public VMTemplateStoragePoolVO prepareTemplateForCreate(VMTemplateVO templ, StoragePool pool) {
|
public VMTemplateStoragePoolVO prepareTemplateForCreate(VMTemplateVO templ, StoragePool pool) {
|
||||||
VMTemplateVO template = _tmpltDao.findById(templ.getId(), true);
|
VMTemplateVO template = _tmpltDao.findById(templ.getId(), true);
|
||||||
|
|
||||||
long poolId = pool.getId();
|
long poolId = pool.getId();
|
||||||
long templateId = template.getId();
|
long templateId = template.getId();
|
||||||
long dcId = pool.getDataCenterId();
|
long dcId = pool.getDataCenterId();
|
||||||
@ -656,23 +662,23 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
VMTemplateHostVO templateHostRef = null;
|
VMTemplateHostVO templateHostRef = null;
|
||||||
long templateStoragePoolRefId;
|
long templateStoragePoolRefId;
|
||||||
String origUrl = null;
|
String origUrl = null;
|
||||||
|
|
||||||
templateStoragePoolRef = _tmpltPoolDao.findByPoolTemplate(poolId, templateId);
|
templateStoragePoolRef = _tmpltPoolDao.findByPoolTemplate(poolId, templateId);
|
||||||
if (templateStoragePoolRef != null) {
|
if (templateStoragePoolRef != null) {
|
||||||
templateStoragePoolRef.setMarkedForGC(false);
|
templateStoragePoolRef.setMarkedForGC(false);
|
||||||
_tmpltPoolDao.update(templateStoragePoolRef.getId(), templateStoragePoolRef);
|
_tmpltPoolDao.update(templateStoragePoolRef.getId(), templateStoragePoolRef);
|
||||||
|
|
||||||
if (templateStoragePoolRef.getDownloadState() == Status.DOWNLOADED) {
|
if (templateStoragePoolRef.getDownloadState() == Status.DOWNLOADED) {
|
||||||
if (s_logger.isDebugEnabled()) {
|
if (s_logger.isDebugEnabled()) {
|
||||||
s_logger.debug("Template " + templateId + " has already been downloaded to pool " + poolId);
|
s_logger.debug("Template " + templateId + " has already been downloaded to pool " + poolId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return templateStoragePoolRef;
|
return templateStoragePoolRef;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
templateHostRef = findVmTemplateHost(templateId, pool);
|
templateHostRef = findVmTemplateHost(templateId, pool);
|
||||||
|
|
||||||
if (templateHostRef == null || templateHostRef.getDownloadState() != Status.DOWNLOADED) {
|
if (templateHostRef == null || templateHostRef.getDownloadState() != Status.DOWNLOADED) {
|
||||||
String result = downloadTemplateFromSwiftToSecondaryStorage(dcId, templateId);
|
String result = downloadTemplateFromSwiftToSecondaryStorage(dcId, templateId);
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
@ -691,13 +697,13 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
HostVO sh = _hostDao.findById(templateHostRef.getHostId());
|
HostVO sh = _hostDao.findById(templateHostRef.getHostId());
|
||||||
origUrl = sh.getStorageUrl();
|
origUrl = sh.getStorageUrl();
|
||||||
if (origUrl == null) {
|
if (origUrl == null) {
|
||||||
throw new CloudRuntimeException("Unable to find the orig.url from host " + sh.toString());
|
throw new CloudRuntimeException("Unable to find the orig.url from host " + sh.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (templateStoragePoolRef == null) {
|
if (templateStoragePoolRef == null) {
|
||||||
if (s_logger.isDebugEnabled()) {
|
if (s_logger.isDebugEnabled()) {
|
||||||
s_logger.debug("Downloading template " + templateId + " to pool " + poolId);
|
s_logger.debug("Downloading template " + templateId + " to pool " + poolId);
|
||||||
@ -706,7 +712,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
try {
|
try {
|
||||||
templateStoragePoolRef = _tmpltPoolDao.persist(templateStoragePoolRef);
|
templateStoragePoolRef = _tmpltPoolDao.persist(templateStoragePoolRef);
|
||||||
templateStoragePoolRefId = templateStoragePoolRef.getId();
|
templateStoragePoolRefId = templateStoragePoolRef.getId();
|
||||||
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
s_logger.debug("Assuming we're in a race condition: " + e.getMessage());
|
s_logger.debug("Assuming we're in a race condition: " + e.getMessage());
|
||||||
templateStoragePoolRef = _tmpltPoolDao.findByPoolTemplate(poolId, templateId);
|
templateStoragePoolRef = _tmpltPoolDao.findByPoolTemplate(poolId, templateId);
|
||||||
@ -718,12 +724,12 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
} else {
|
} else {
|
||||||
templateStoragePoolRefId = templateStoragePoolRef.getId();
|
templateStoragePoolRefId = templateStoragePoolRef.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
List<StoragePoolHostVO> vos = _poolHostDao.listByHostStatus(poolId, com.cloud.host.Status.Up);
|
List<StoragePoolHostVO> vos = _poolHostDao.listByHostStatus(poolId, com.cloud.host.Status.Up);
|
||||||
if (vos == null || vos.isEmpty()){
|
if (vos == null || vos.isEmpty()){
|
||||||
throw new CloudRuntimeException("Cannot download " + templateId + " to poolId " + poolId + " since there is no host in the Up state connected to this pool");
|
throw new CloudRuntimeException("Cannot download " + templateId + " to poolId " + poolId + " since there is no host in the Up state connected to this pool");
|
||||||
}
|
}
|
||||||
|
|
||||||
templateStoragePoolRef = _tmpltPoolDao.acquireInLockTable(templateStoragePoolRefId, _storagePoolMaxWaitSeconds);
|
templateStoragePoolRef = _tmpltPoolDao.acquireInLockTable(templateStoragePoolRefId, _storagePoolMaxWaitSeconds);
|
||||||
if (templateStoragePoolRef == null) {
|
if (templateStoragePoolRef == null) {
|
||||||
throw new CloudRuntimeException("Unable to acquire lock on VMTemplateStoragePool: " + templateStoragePoolRefId);
|
throw new CloudRuntimeException("Unable to acquire lock on VMTemplateStoragePool: " + templateStoragePoolRefId);
|
||||||
@ -734,13 +740,13 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
return templateStoragePoolRef;
|
return templateStoragePoolRef;
|
||||||
}
|
}
|
||||||
String url = origUrl + "/" + templateHostRef.getInstallPath();
|
String url = origUrl + "/" + templateHostRef.getInstallPath();
|
||||||
PrimaryStorageDownloadCommand dcmd = new PrimaryStorageDownloadCommand(template.getUniqueName(), url, template.getFormat(),
|
PrimaryStorageDownloadCommand dcmd = new PrimaryStorageDownloadCommand(template.getUniqueName(), url, template.getFormat(),
|
||||||
template.getAccountId(), pool, _primaryStorageDownloadWait);
|
template.getAccountId(), pool, _primaryStorageDownloadWait);
|
||||||
HostVO secondaryStorageHost = _hostDao.findById(templateHostRef.getHostId());
|
HostVO secondaryStorageHost = _hostDao.findById(templateHostRef.getHostId());
|
||||||
assert(secondaryStorageHost != null);
|
assert(secondaryStorageHost != null);
|
||||||
dcmd.setSecondaryStorageUrl(secondaryStorageHost.getStorageUrl());
|
dcmd.setSecondaryStorageUrl(secondaryStorageHost.getStorageUrl());
|
||||||
|
|
||||||
|
|
||||||
for (int retry = 0; retry < 2; retry ++){
|
for (int retry = 0; retry < 2; retry ++){
|
||||||
Collections.shuffle(vos); // Shuffling to pick a random host in the vm deployment retries
|
Collections.shuffle(vos); // Shuffling to pick a random host in the vm deployment retries
|
||||||
StoragePoolHostVO vo = vos.get(0);
|
StoragePoolHostVO vo = vos.get(0);
|
||||||
@ -749,7 +755,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
}
|
}
|
||||||
dcmd.setLocalPath(vo.getLocalPath());
|
dcmd.setLocalPath(vo.getLocalPath());
|
||||||
// set 120 min timeout for this command
|
// set 120 min timeout for this command
|
||||||
|
|
||||||
PrimaryStorageDownloadAnswer answer = (PrimaryStorageDownloadAnswer)_agentMgr.easySend(
|
PrimaryStorageDownloadAnswer answer = (PrimaryStorageDownloadAnswer)_agentMgr.easySend(
|
||||||
_hvGuruMgr.getGuruProcessedCommandTargetHost(vo.getHostId(), dcmd), dcmd);
|
_hvGuruMgr.getGuruProcessedCommandTargetHost(vo.getHostId(), dcmd), dcmd);
|
||||||
if (answer != null && answer.getResult() ) {
|
if (answer != null && answer.getResult() ) {
|
||||||
@ -776,10 +782,10 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VMTemplateHostVO findVmTemplateHost(long templateId,
|
public VMTemplateHostVO findVmTemplateHost(long templateId,
|
||||||
StoragePool pool) {
|
StoragePool pool) {
|
||||||
@ -813,7 +819,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getChecksum(Long hostId, String templatePath) {
|
public String getChecksum(Long hostId, String templatePath) {
|
||||||
HostVO ssHost = _hostDao.findById(hostId);
|
HostVO ssHost = _hostDao.findById(hostId);
|
||||||
@ -831,7 +837,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@DB
|
@DB
|
||||||
public VMTemplateHostVO prepareISOForCreate(VMTemplateVO template, StoragePool pool) {
|
public VMTemplateHostVO prepareISOForCreate(VMTemplateVO template, StoragePool pool) {
|
||||||
@ -873,22 +879,22 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
public boolean resetTemplateDownloadStateOnPool(long templateStoragePoolRefId) {
|
public boolean resetTemplateDownloadStateOnPool(long templateStoragePoolRefId) {
|
||||||
// have to use the same lock that prepareTemplateForCreate use to maintain state consistency
|
// have to use the same lock that prepareTemplateForCreate use to maintain state consistency
|
||||||
VMTemplateStoragePoolVO templateStoragePoolRef = _tmpltPoolDao.acquireInLockTable(templateStoragePoolRefId, 1200);
|
VMTemplateStoragePoolVO templateStoragePoolRef = _tmpltPoolDao.acquireInLockTable(templateStoragePoolRefId, 1200);
|
||||||
|
|
||||||
if (templateStoragePoolRef == null) {
|
if (templateStoragePoolRef == null) {
|
||||||
s_logger.warn("resetTemplateDownloadStateOnPool failed - unable to lock TemplateStorgePoolRef " + templateStoragePoolRefId);
|
s_logger.warn("resetTemplateDownloadStateOnPool failed - unable to lock TemplateStorgePoolRef " + templateStoragePoolRefId);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
templateStoragePoolRef.setDownloadState(VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED);
|
templateStoragePoolRef.setDownloadState(VMTemplateStorageResourceAssoc.Status.NOT_DOWNLOADED);
|
||||||
_tmpltPoolDao.update(templateStoragePoolRefId, templateStoragePoolRef);
|
_tmpltPoolDao.update(templateStoragePoolRefId, templateStoragePoolRef);
|
||||||
} finally {
|
} finally {
|
||||||
_tmpltPoolDao.releaseFromLockTable(templateStoragePoolRefId);
|
_tmpltPoolDao.releaseFromLockTable(templateStoragePoolRefId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@DB
|
@DB
|
||||||
public boolean copy(long userId, VMTemplateVO template, HostVO srcSecHost, DataCenterVO srcZone, DataCenterVO dstZone) throws StorageUnavailableException, ResourceAllocationException {
|
public boolean copy(long userId, VMTemplateVO template, HostVO srcSecHost, DataCenterVO srcZone, DataCenterVO dstZone) throws StorageUnavailableException, ResourceAllocationException {
|
||||||
@ -930,7 +936,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
} else {
|
} else {
|
||||||
dstTmpltHost.setDestroyed(false);
|
dstTmpltHost.setDestroyed(false);
|
||||||
_tmpltHostDao.update(dstTmpltHost.getId(), dstTmpltHost);
|
_tmpltHostDao.update(dstTmpltHost.getId(), dstTmpltHost);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} else if (dstTmpltHost != null && dstTmpltHost.getDownloadState() == Status.DOWNLOAD_ERROR){
|
} else if (dstTmpltHost != null && dstTmpltHost.getDownloadState() == Status.DOWNLOAD_ERROR){
|
||||||
@ -951,7 +957,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
|
|
||||||
if(_downloadMonitor.copyTemplate(template, srcSecHost, dstSecHost) ) {
|
if(_downloadMonitor.copyTemplate(template, srcSecHost, dstSecHost) ) {
|
||||||
_tmpltDao.addTemplateToZone(template, dstZoneId);
|
_tmpltDao.addTemplateToZone(template, dstZoneId);
|
||||||
|
|
||||||
if(account.getId() != Account.ACCOUNT_ID_SYSTEM){
|
if(account.getId() != Account.ACCOUNT_ID_SYSTEM){
|
||||||
UsageEventUtils.publishUsageEvent(copyEventType, account.getId(), dstZoneId, tmpltId, null, null, null, srcTmpltHost.getSize(),
|
UsageEventUtils.publishUsageEvent(copyEventType, account.getId(), dstZoneId, tmpltId, null, null, null, srcTmpltHost.getSize(),
|
||||||
template.getClass().getName(), template.getUuid());
|
template.getClass().getName(), template.getUuid());
|
||||||
@ -961,8 +967,8 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_COPY, eventDescription = "copying template", async = true)
|
@ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_COPY, eventDescription = "copying template", async = true)
|
||||||
public VirtualMachineTemplate copyTemplate(CopyTemplateCmd cmd) throws StorageUnavailableException, ResourceAllocationException {
|
public VirtualMachineTemplate copyTemplate(CopyTemplateCmd cmd) throws StorageUnavailableException, ResourceAllocationException {
|
||||||
@ -971,7 +977,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
Long sourceZoneId = cmd.getSourceZoneId();
|
Long sourceZoneId = cmd.getSourceZoneId();
|
||||||
Long destZoneId = cmd.getDestinationZoneId();
|
Long destZoneId = cmd.getDestinationZoneId();
|
||||||
Account caller = UserContext.current().getCaller();
|
Account caller = UserContext.current().getCaller();
|
||||||
|
|
||||||
if (_swiftMgr.isSwiftEnabled()) {
|
if (_swiftMgr.isSwiftEnabled()) {
|
||||||
throw new CloudRuntimeException("copytemplate API is disabled in Swift setup, templates in Swift can be accessed by all Zones");
|
throw new CloudRuntimeException("copytemplate API is disabled in Swift setup, templates in Swift can be accessed by all Zones");
|
||||||
}
|
}
|
||||||
@ -985,37 +991,37 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
if (sourceZoneId == destZoneId) {
|
if (sourceZoneId == destZoneId) {
|
||||||
throw new InvalidParameterValueException("Please specify different source and destination zones.");
|
throw new InvalidParameterValueException("Please specify different source and destination zones.");
|
||||||
}
|
}
|
||||||
|
|
||||||
DataCenterVO sourceZone = _dcDao.findById(sourceZoneId);
|
DataCenterVO sourceZone = _dcDao.findById(sourceZoneId);
|
||||||
if (sourceZone == null) {
|
if (sourceZone == null) {
|
||||||
throw new InvalidParameterValueException("Please specify a valid source zone.");
|
throw new InvalidParameterValueException("Please specify a valid source zone.");
|
||||||
}
|
}
|
||||||
|
|
||||||
DataCenterVO dstZone = _dcDao.findById(destZoneId);
|
DataCenterVO dstZone = _dcDao.findById(destZoneId);
|
||||||
if (dstZone == null) {
|
if (dstZone == null) {
|
||||||
throw new InvalidParameterValueException("Please specify a valid destination zone.");
|
throw new InvalidParameterValueException("Please specify a valid destination zone.");
|
||||||
}
|
}
|
||||||
|
|
||||||
VMTemplateVO template = _tmpltDao.findById(templateId);
|
VMTemplateVO template = _tmpltDao.findById(templateId);
|
||||||
if (template == null || template.getRemoved() != null) {
|
if (template == null || template.getRemoved() != null) {
|
||||||
throw new InvalidParameterValueException("Unable to find template with id");
|
throw new InvalidParameterValueException("Unable to find template with id");
|
||||||
}
|
}
|
||||||
|
|
||||||
HostVO dstSecHost = getSecondaryStorageHost(destZoneId, templateId);
|
HostVO dstSecHost = getSecondaryStorageHost(destZoneId, templateId);
|
||||||
if ( dstSecHost != null ) {
|
if ( dstSecHost != null ) {
|
||||||
s_logger.debug("There is template " + templateId + " in secondary storage " + dstSecHost.getId() + " in zone " + destZoneId + " , don't need to copy");
|
s_logger.debug("There is template " + templateId + " in secondary storage " + dstSecHost.getId() + " in zone " + destZoneId + " , don't need to copy");
|
||||||
return template;
|
return template;
|
||||||
}
|
}
|
||||||
|
|
||||||
HostVO srcSecHost = getSecondaryStorageHost(sourceZoneId, templateId);
|
HostVO srcSecHost = getSecondaryStorageHost(sourceZoneId, templateId);
|
||||||
if ( srcSecHost == null ) {
|
if ( srcSecHost == null ) {
|
||||||
throw new InvalidParameterValueException("There is no template " + templateId + " in zone " + sourceZoneId );
|
throw new InvalidParameterValueException("There is no template " + templateId + " in zone " + sourceZoneId );
|
||||||
}
|
}
|
||||||
|
|
||||||
_accountMgr.checkAccess(caller, AccessType.ModifyEntry, true, template);
|
_accountMgr.checkAccess(caller, AccessType.ModifyEntry, true, template);
|
||||||
|
|
||||||
boolean success = copy(userId, template, srcSecHost, sourceZone, dstZone);
|
boolean success = copy(userId, template, srcSecHost, sourceZone, dstZone);
|
||||||
|
|
||||||
if (success){
|
if (success){
|
||||||
return template;
|
return template;
|
||||||
}else {
|
}else {
|
||||||
@ -1029,24 +1035,24 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
if (template == null || template.getRemoved() != null) {
|
if (template == null || template.getRemoved() != null) {
|
||||||
throw new InvalidParameterValueException("Please specify a valid template.");
|
throw new InvalidParameterValueException("Please specify a valid template.");
|
||||||
}
|
}
|
||||||
|
|
||||||
TemplateAdapter adapter = getAdapter(template.getHypervisorType());
|
TemplateAdapter adapter = getAdapter(template.getHypervisorType());
|
||||||
return adapter.delete(new TemplateProfile(userId, template, zoneId));
|
return adapter.delete(new TemplateProfile(userId, template, zoneId));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<VMTemplateStoragePoolVO> getUnusedTemplatesInPool(StoragePoolVO pool) {
|
public List<VMTemplateStoragePoolVO> getUnusedTemplatesInPool(StoragePoolVO pool) {
|
||||||
List<VMTemplateStoragePoolVO> unusedTemplatesInPool = new ArrayList<VMTemplateStoragePoolVO>();
|
List<VMTemplateStoragePoolVO> unusedTemplatesInPool = new ArrayList<VMTemplateStoragePoolVO>();
|
||||||
List<VMTemplateStoragePoolVO> allTemplatesInPool = _tmpltPoolDao.listByPoolId(pool.getId());
|
List<VMTemplateStoragePoolVO> allTemplatesInPool = _tmpltPoolDao.listByPoolId(pool.getId());
|
||||||
|
|
||||||
for (VMTemplateStoragePoolVO templatePoolVO : allTemplatesInPool) {
|
for (VMTemplateStoragePoolVO templatePoolVO : allTemplatesInPool) {
|
||||||
VMTemplateVO template = _tmpltDao.findByIdIncludingRemoved(templatePoolVO.getTemplateId());
|
VMTemplateVO template = _tmpltDao.findByIdIncludingRemoved(templatePoolVO.getTemplateId());
|
||||||
|
|
||||||
// If this is a routing template, consider it in use
|
// If this is a routing template, consider it in use
|
||||||
if (template.getTemplateType() == TemplateType.SYSTEM) {
|
if (template.getTemplateType() == TemplateType.SYSTEM) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the template is not yet downloaded to the pool, consider it in use
|
// If the template is not yet downloaded to the pool, consider it in use
|
||||||
if (templatePoolVO.getDownloadState() != Status.DOWNLOADED) {
|
if (templatePoolVO.getDownloadState() != Status.DOWNLOADED) {
|
||||||
continue;
|
continue;
|
||||||
@ -1056,24 +1062,24 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
unusedTemplatesInPool.add(templatePoolVO);
|
unusedTemplatesInPool.add(templatePoolVO);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return unusedTemplatesInPool;
|
return unusedTemplatesInPool;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void evictTemplateFromStoragePool(VMTemplateStoragePoolVO templatePoolVO) {
|
public void evictTemplateFromStoragePool(VMTemplateStoragePoolVO templatePoolVO) {
|
||||||
StoragePool pool = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(templatePoolVO.getPoolId());
|
StoragePool pool = (StoragePool)this.dataStoreMgr.getPrimaryDataStore(templatePoolVO.getPoolId());
|
||||||
VMTemplateVO template = _tmpltDao.findByIdIncludingRemoved(templatePoolVO.getTemplateId());
|
VMTemplateVO template = _tmpltDao.findByIdIncludingRemoved(templatePoolVO.getTemplateId());
|
||||||
|
|
||||||
|
|
||||||
if (s_logger.isDebugEnabled()) {
|
if (s_logger.isDebugEnabled()) {
|
||||||
s_logger.debug("Evicting " + templatePoolVO);
|
s_logger.debug("Evicting " + templatePoolVO);
|
||||||
}
|
}
|
||||||
DestroyCommand cmd = new DestroyCommand(pool, templatePoolVO);
|
DestroyCommand cmd = new DestroyCommand(pool, templatePoolVO);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Answer answer = _storageMgr.sendToPool(pool, cmd);
|
Answer answer = _storageMgr.sendToPool(pool, cmd);
|
||||||
|
|
||||||
if (answer != null && answer.getResult()) {
|
if (answer != null && answer.getResult()) {
|
||||||
// Remove the templatePoolVO
|
// Remove the templatePoolVO
|
||||||
if (_tmpltPoolDao.remove(templatePoolVO.getId())) {
|
if (_tmpltPoolDao.remove(templatePoolVO.getId())) {
|
||||||
@ -1087,7 +1093,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void swiftTemplateSync() {
|
void swiftTemplateSync() {
|
||||||
GlobalLock swiftTemplateSyncLock = GlobalLock.getInternLock("templatemgr.swiftTemplateSync");
|
GlobalLock swiftTemplateSyncLock = GlobalLock.getInternLock("templatemgr.swiftTemplateSync");
|
||||||
try {
|
try {
|
||||||
@ -1187,7 +1193,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
|
||||||
|
|
||||||
final Map<String, String> configs = _configDao.getConfiguration("AgentManager", params);
|
final Map<String, String> configs = _configDao.getConfiguration("AgentManager", params);
|
||||||
_routerTemplateId = NumbersUtil.parseInt(configs.get("router.template.id"), 1);
|
_routerTemplateId = NumbersUtil.parseInt(configs.get("router.template.id"), 1);
|
||||||
|
|
||||||
@ -1200,14 +1206,14 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
HostTemplateStatesSearch = _tmpltHostDao.createSearchBuilder();
|
HostTemplateStatesSearch = _tmpltHostDao.createSearchBuilder();
|
||||||
HostTemplateStatesSearch.and("id", HostTemplateStatesSearch.entity().getTemplateId(), SearchCriteria.Op.EQ);
|
HostTemplateStatesSearch.and("id", HostTemplateStatesSearch.entity().getTemplateId(), SearchCriteria.Op.EQ);
|
||||||
HostTemplateStatesSearch.and("state", HostTemplateStatesSearch.entity().getDownloadState(), SearchCriteria.Op.EQ);
|
HostTemplateStatesSearch.and("state", HostTemplateStatesSearch.entity().getDownloadState(), SearchCriteria.Op.EQ);
|
||||||
|
|
||||||
SearchBuilder<HostVO> HostSearch = _hostDao.createSearchBuilder();
|
SearchBuilder<HostVO> HostSearch = _hostDao.createSearchBuilder();
|
||||||
HostSearch.and("dcId", HostSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
|
HostSearch.and("dcId", HostSearch.entity().getDataCenterId(), SearchCriteria.Op.EQ);
|
||||||
|
|
||||||
HostTemplateStatesSearch.join("host", HostSearch, HostSearch.entity().getId(), HostTemplateStatesSearch.entity().getHostId(), JoinBuilder.JoinType.INNER);
|
HostTemplateStatesSearch.join("host", HostSearch, HostSearch.entity().getId(), HostTemplateStatesSearch.entity().getHostId(), JoinBuilder.JoinType.INNER);
|
||||||
HostSearch.done();
|
HostSearch.done();
|
||||||
HostTemplateStatesSearch.done();
|
HostTemplateStatesSearch.done();
|
||||||
|
|
||||||
_storagePoolMaxWaitSeconds = NumbersUtil.parseInt(_configDao.getValue(Config.StoragePoolMaxWaitSeconds.key()), 3600);
|
_storagePoolMaxWaitSeconds = NumbersUtil.parseInt(_configDao.getValue(Config.StoragePoolMaxWaitSeconds.key()), 3600);
|
||||||
_preloadExecutor = Executors.newFixedThreadPool(8, new NamedThreadFactory("Template-Preloader"));
|
_preloadExecutor = Executors.newFixedThreadPool(8, new NamedThreadFactory("Template-Preloader"));
|
||||||
_swiftTemplateSyncExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("swift-template-sync-Executor"));
|
_swiftTemplateSyncExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("swift-template-sync-Executor"));
|
||||||
@ -1222,7 +1228,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected TemplateManagerImpl() {
|
protected TemplateManagerImpl() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1260,23 +1266,57 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean templateIsDeleteable(TemplateDataStoreVO templateStoreRef) {
|
||||||
|
VMTemplateVO template = _tmpltDao.findByIdIncludingRemoved(templateStoreRef.getTemplateId());
|
||||||
|
long templateId = template.getId();
|
||||||
|
ImageStoreVO imageStore = _imageStoreDao.findById(templateStoreRef.getDataStoreId());
|
||||||
|
long zoneId = imageStore.getDataCenterId();
|
||||||
|
DataCenterVO zone = _dcDao.findById(zoneId);
|
||||||
|
|
||||||
|
// Check if there are VMs running in the template host ref's zone that use the template
|
||||||
|
List<VMInstanceVO> nonExpungedVms = _vmInstanceDao.listNonExpungedByZoneAndTemplate(zoneId, templateId);
|
||||||
|
|
||||||
|
if (!nonExpungedVms.isEmpty()) {
|
||||||
|
s_logger.debug("Template " + template.getName() + " in zone " + zone.getName() + " is not deleteable because there are non-expunged VMs deployed from this template.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
List<UserVmVO> userVmUsingIso = _userVmDao.listByIsoId(templateId);
|
||||||
|
//check if there is any VM using this ISO.
|
||||||
|
if (!userVmUsingIso.isEmpty()) {
|
||||||
|
s_logger.debug("ISO " + template.getName() + " in zone " + zone.getName() + " is not deleteable because it is attached to " + userVmUsingIso.size() + " VMs");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Check if there are any snapshots for the template in the template host ref's zone
|
||||||
|
List<VolumeVO> volumes = _volumeDao.findByTemplateAndZone(templateId, zoneId);
|
||||||
|
for (VolumeVO volume : volumes) {
|
||||||
|
List<SnapshotVO> snapshots = _snapshotDao.listByVolumeIdVersion(volume.getId(), "2.1");
|
||||||
|
if (!snapshots.isEmpty()) {
|
||||||
|
s_logger.debug("Template " + template.getName() + " in zone " + zone.getName() + " is not deleteable because there are 2.1 snapshots using this template.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ActionEvent(eventType = EventTypes.EVENT_ISO_DETACH, eventDescription = "detaching ISO", async = true)
|
@ActionEvent(eventType = EventTypes.EVENT_ISO_DETACH, eventDescription = "detaching ISO", async = true)
|
||||||
public boolean detachIso(long vmId) {
|
public boolean detachIso(long vmId) {
|
||||||
Account caller = UserContext.current().getCaller();
|
Account caller = UserContext.current().getCaller();
|
||||||
Long userId = UserContext.current().getCallerUserId();
|
Long userId = UserContext.current().getCallerUserId();
|
||||||
|
|
||||||
// Verify input parameters
|
// Verify input parameters
|
||||||
UserVmVO vmInstanceCheck = _userVmDao.findById(vmId);
|
UserVmVO vmInstanceCheck = _userVmDao.findById(vmId);
|
||||||
if (vmInstanceCheck == null) {
|
if (vmInstanceCheck == null) {
|
||||||
throw new InvalidParameterValueException ("Unable to find a virtual machine with id " + vmId);
|
throw new InvalidParameterValueException ("Unable to find a virtual machine with id " + vmId);
|
||||||
}
|
}
|
||||||
|
|
||||||
UserVm userVM = _userVmDao.findById(vmId);
|
UserVm userVM = _userVmDao.findById(vmId);
|
||||||
if (userVM == null) {
|
if (userVM == null) {
|
||||||
throw new InvalidParameterValueException("Please specify a valid VM.");
|
throw new InvalidParameterValueException("Please specify a valid VM.");
|
||||||
}
|
}
|
||||||
|
|
||||||
_accountMgr.checkAccess(caller, null, true, userVM);
|
_accountMgr.checkAccess(caller, null, true, userVM);
|
||||||
|
|
||||||
Long isoId = userVM.getIsoId();
|
Long isoId = userVM.getIsoId();
|
||||||
@ -1284,7 +1324,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
throw new InvalidParameterValueException("The specified VM has no ISO attached to it.");
|
throw new InvalidParameterValueException("The specified VM has no ISO attached to it.");
|
||||||
}
|
}
|
||||||
UserContext.current().setEventDetails("Vm Id: " +vmId+ " ISO Id: "+isoId);
|
UserContext.current().setEventDetails("Vm Id: " +vmId+ " ISO Id: "+isoId);
|
||||||
|
|
||||||
State vmState = userVM.getState();
|
State vmState = userVM.getState();
|
||||||
if (vmState != State.Running && vmState != State.Stopped) {
|
if (vmState != State.Running && vmState != State.Stopped) {
|
||||||
throw new InvalidParameterValueException("Please specify a VM that is either Stopped or Running.");
|
throw new InvalidParameterValueException("Please specify a VM that is either Stopped or Running.");
|
||||||
@ -1295,44 +1335,44 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
return result;
|
return result;
|
||||||
}else {
|
}else {
|
||||||
throw new CloudRuntimeException("Failed to detach iso");
|
throw new CloudRuntimeException("Failed to detach iso");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ActionEvent(eventType = EventTypes.EVENT_ISO_ATTACH, eventDescription = "attaching ISO", async = true)
|
@ActionEvent(eventType = EventTypes.EVENT_ISO_ATTACH, eventDescription = "attaching ISO", async = true)
|
||||||
public boolean attachIso(long isoId, long vmId) {
|
public boolean attachIso(long isoId, long vmId) {
|
||||||
Account caller = UserContext.current().getCaller();
|
Account caller = UserContext.current().getCaller();
|
||||||
Long userId = UserContext.current().getCallerUserId();
|
Long userId = UserContext.current().getCallerUserId();
|
||||||
|
|
||||||
// Verify input parameters
|
// Verify input parameters
|
||||||
UserVmVO vm = _userVmDao.findById(vmId);
|
UserVmVO vm = _userVmDao.findById(vmId);
|
||||||
if (vm == null) {
|
if (vm == null) {
|
||||||
throw new InvalidParameterValueException("Unable to find a virtual machine with id " + vmId);
|
throw new InvalidParameterValueException("Unable to find a virtual machine with id " + vmId);
|
||||||
}
|
}
|
||||||
|
|
||||||
VMTemplateVO iso = _tmpltDao.findById(isoId);
|
VMTemplateVO iso = _tmpltDao.findById(isoId);
|
||||||
if (iso == null || iso.getRemoved() != null) {
|
if (iso == null || iso.getRemoved() != null) {
|
||||||
throw new InvalidParameterValueException("Unable to find an ISO with id " + isoId);
|
throw new InvalidParameterValueException("Unable to find an ISO with id " + isoId);
|
||||||
}
|
}
|
||||||
|
|
||||||
//check permissions
|
//check permissions
|
||||||
//check if caller has access to VM and ISO
|
//check if caller has access to VM and ISO
|
||||||
//and also check if the VM's owner has access to the ISO.
|
//and also check if the VM's owner has access to the ISO.
|
||||||
|
|
||||||
_accountMgr.checkAccess(caller, null, false, iso, vm);
|
_accountMgr.checkAccess(caller, null, false, iso, vm);
|
||||||
|
|
||||||
Account vmOwner = _accountDao.findById(vm.getAccountId());
|
Account vmOwner = _accountDao.findById(vm.getAccountId());
|
||||||
_accountMgr.checkAccess(vmOwner, null, false, iso, vm);
|
_accountMgr.checkAccess(vmOwner, null, false, iso, vm);
|
||||||
|
|
||||||
State vmState = vm.getState();
|
State vmState = vm.getState();
|
||||||
if (vmState != State.Running && vmState != State.Stopped) {
|
if (vmState != State.Running && vmState != State.Stopped) {
|
||||||
throw new InvalidParameterValueException("Please specify a VM that is either Stopped or Running.");
|
throw new InvalidParameterValueException("Please specify a VM that is either Stopped or Running.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("xen-pv-drv-iso".equals(iso.getDisplayText()) && vm.getHypervisorType() != Hypervisor.HypervisorType.XenServer){
|
if ("xen-pv-drv-iso".equals(iso.getDisplayText()) && vm.getHypervisorType() != Hypervisor.HypervisorType.XenServer){
|
||||||
throw new InvalidParameterValueException("Cannot attach Xenserver PV drivers to incompatible hypervisor " + vm.getHypervisorType());
|
throw new InvalidParameterValueException("Cannot attach Xenserver PV drivers to incompatible hypervisor " + vm.getHypervisorType());
|
||||||
}
|
}
|
||||||
|
|
||||||
if("vmware-tools.iso".equals(iso.getName()) && vm.getHypervisorType() != Hypervisor.HypervisorType.VMware) {
|
if("vmware-tools.iso".equals(iso.getName()) && vm.getHypervisorType() != Hypervisor.HypervisorType.VMware) {
|
||||||
throw new InvalidParameterValueException("Cannot attach VMware tools drivers to incompatible hypervisor " + vm.getHypervisorType());
|
throw new InvalidParameterValueException("Cannot attach VMware tools drivers to incompatible hypervisor " + vm.getHypervisorType());
|
||||||
}
|
}
|
||||||
@ -1343,7 +1383,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
throw new CloudRuntimeException("Failed to attach iso");
|
throw new CloudRuntimeException("Failed to attach iso");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean attachISOToVM(long vmId, long isoId, boolean attach) {
|
private boolean attachISOToVM(long vmId, long isoId, boolean attach) {
|
||||||
UserVmVO vm = this._userVmDao.findById(vmId);
|
UserVmVO vm = this._userVmDao.findById(vmId);
|
||||||
|
|
||||||
@ -1397,41 +1437,43 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
if ( success && attach) {
|
if ( success && attach) {
|
||||||
vm.setIsoId(iso.getId());
|
vm.setIsoId(iso.getId());
|
||||||
_userVmDao.update(vmId, vm);
|
_userVmDao.update(vmId, vm);
|
||||||
}
|
}
|
||||||
if ( success && !attach ) {
|
if ( success && !attach ) {
|
||||||
vm.setIsoId(null);
|
vm.setIsoId(null);
|
||||||
_userVmDao.update(vmId, vm);
|
_userVmDao.update(vmId, vm);
|
||||||
}
|
}
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_DELETE, eventDescription = "deleting template", async = true)
|
@ActionEvent(eventType = EventTypes.EVENT_TEMPLATE_DELETE, eventDescription = "deleting template", async = true)
|
||||||
public boolean deleteTemplate(DeleteTemplateCmd cmd) {
|
public boolean deleteTemplate(DeleteTemplateCmd cmd) {
|
||||||
Long templateId = cmd.getId();
|
Long templateId = cmd.getId();
|
||||||
Account caller = UserContext.current().getCaller();
|
Account caller = UserContext.current().getCaller();
|
||||||
|
|
||||||
VirtualMachineTemplate template = getTemplate(templateId);
|
VirtualMachineTemplate template = getTemplate(templateId);
|
||||||
if (template == null) {
|
if (template == null) {
|
||||||
throw new InvalidParameterValueException("unable to find template with id " + templateId);
|
throw new InvalidParameterValueException("unable to find template with id " + templateId);
|
||||||
}
|
}
|
||||||
|
|
||||||
_accountMgr.checkAccess(caller, AccessType.ModifyEntry, true, template);
|
_accountMgr.checkAccess(caller, AccessType.ModifyEntry, true, template);
|
||||||
|
|
||||||
if (template.getFormat() == ImageFormat.ISO) {
|
if (template.getFormat() == ImageFormat.ISO) {
|
||||||
throw new InvalidParameterValueException("Please specify a valid template.");
|
throw new InvalidParameterValueException("Please specify a valid template.");
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
if (cmd.getZoneId() == null && _swiftMgr.isSwiftEnabled()) {
|
if (cmd.getZoneId() == null && _swiftMgr.isSwiftEnabled()) {
|
||||||
_swiftMgr.deleteTemplate(cmd);
|
_swiftMgr.deleteTemplate(cmd);
|
||||||
}
|
}
|
||||||
if (cmd.getZoneId() == null && _s3Mgr.isS3Enabled()) {
|
if (cmd.getZoneId() == null && _s3Mgr.isS3Enabled()) {
|
||||||
_s3Mgr.deleteTemplate(cmd.getId(), caller.getAccountId());
|
_s3Mgr.deleteTemplate(cmd.getId(), caller.getAccountId());
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
TemplateAdapter adapter = getAdapter(template.getHypervisorType());
|
TemplateAdapter adapter = getAdapter(template.getHypervisorType());
|
||||||
TemplateProfile profile = adapter.prepareDelete(cmd);
|
TemplateProfile profile = adapter.prepareDelete(cmd);
|
||||||
boolean result = adapter.delete(profile);
|
boolean result = adapter.delete(profile);
|
||||||
|
|
||||||
if (result){
|
if (result){
|
||||||
if (cmd.getZoneId() == null
|
if (cmd.getZoneId() == null
|
||||||
&& (_swiftMgr.isSwiftEnabled() || _s3Mgr.isS3Enabled())) {
|
&& (_swiftMgr.isSwiftEnabled() || _s3Mgr.isS3Enabled())) {
|
||||||
@ -1448,21 +1490,21 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
throw new CloudRuntimeException("Failed to delete template");
|
throw new CloudRuntimeException("Failed to delete template");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ActionEvent(eventType = EventTypes.EVENT_ISO_DELETE, eventDescription = "deleting iso", async = true)
|
@ActionEvent(eventType = EventTypes.EVENT_ISO_DELETE, eventDescription = "deleting iso", async = true)
|
||||||
public boolean deleteIso(DeleteIsoCmd cmd) {
|
public boolean deleteIso(DeleteIsoCmd cmd) {
|
||||||
Long templateId = cmd.getId();
|
Long templateId = cmd.getId();
|
||||||
Account caller = UserContext.current().getCaller();
|
Account caller = UserContext.current().getCaller();
|
||||||
Long zoneId = cmd.getZoneId();
|
Long zoneId = cmd.getZoneId();
|
||||||
|
|
||||||
VirtualMachineTemplate template = getTemplate(templateId);;
|
VirtualMachineTemplate template = getTemplate(templateId);;
|
||||||
if (template == null) {
|
if (template == null) {
|
||||||
throw new InvalidParameterValueException("unable to find iso with id " + templateId);
|
throw new InvalidParameterValueException("unable to find iso with id " + templateId);
|
||||||
}
|
}
|
||||||
|
|
||||||
_accountMgr.checkAccess(caller, AccessType.ModifyEntry, true, template);
|
_accountMgr.checkAccess(caller, AccessType.ModifyEntry, true, template);
|
||||||
|
|
||||||
if (template.getFormat() != ImageFormat.ISO) {
|
if (template.getFormat() != ImageFormat.ISO) {
|
||||||
throw new InvalidParameterValueException("Please specify a valid iso.");
|
throw new InvalidParameterValueException("Please specify a valid iso.");
|
||||||
}
|
}
|
||||||
@ -1495,17 +1537,17 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
throw new CloudRuntimeException("Failed to delete ISO");
|
throw new CloudRuntimeException("Failed to delete ISO");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VirtualMachineTemplate getTemplate(long templateId) {
|
public VirtualMachineTemplate getTemplate(long templateId) {
|
||||||
VMTemplateVO template = _tmpltDao.findById(templateId);
|
VMTemplateVO template = _tmpltDao.findById(templateId);
|
||||||
if (template != null && template.getRemoved() == null) {
|
if (template != null && template.getRemoved() == null) {
|
||||||
return template;
|
return template;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<String> listTemplatePermissions(BaseListTemplateOrIsoPermissionsCmd cmd) {
|
public List<String> listTemplatePermissions(BaseListTemplateOrIsoPermissionsCmd cmd) {
|
||||||
Account caller = UserContext.current().getCaller();
|
Account caller = UserContext.current().getCaller();
|
||||||
@ -1519,7 +1561,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
if (template == null) {
|
if (template == null) {
|
||||||
throw new InvalidParameterValueException("unable to find " + cmd.getMediaType() + " with id " + id);
|
throw new InvalidParameterValueException("unable to find " + cmd.getMediaType() + " with id " + id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd instanceof ListTemplatePermissionsCmd) {
|
if (cmd instanceof ListTemplatePermissionsCmd) {
|
||||||
if (template.getFormat().equals(ImageFormat.ISO)) {
|
if (template.getFormat().equals(ImageFormat.ISO)) {
|
||||||
throw new InvalidParameterValueException("Please provide a valid template");
|
throw new InvalidParameterValueException("Please provide a valid template");
|
||||||
@ -1544,7 +1586,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
}
|
}
|
||||||
return accountNames;
|
return accountNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
@DB
|
@DB
|
||||||
@Override
|
@Override
|
||||||
public boolean updateTemplateOrIsoPermissions(BaseUpdateTemplateOrIsoPermissionsCmd cmd) {
|
public boolean updateTemplateOrIsoPermissions(BaseUpdateTemplateOrIsoPermissionsCmd cmd) {
|
||||||
@ -1579,7 +1621,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
throw new InvalidParameterValueException("Please provide a valid iso");
|
throw new InvalidParameterValueException("Please provide a valid iso");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//convert projectIds to accountNames
|
//convert projectIds to accountNames
|
||||||
if (projectIds != null) {
|
if (projectIds != null) {
|
||||||
for (Long projectId : projectIds) {
|
for (Long projectId : projectIds) {
|
||||||
@ -1587,7 +1629,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
if (project == null) {
|
if (project == null) {
|
||||||
throw new InvalidParameterValueException("Unable to find project by id " + projectId);
|
throw new InvalidParameterValueException("Unable to find project by id " + projectId);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_projectMgr.canAccessProjectAccount(caller, project.getProjectAccountId())) {
|
if (!_projectMgr.canAccessProjectAccount(caller, project.getProjectAccountId())) {
|
||||||
throw new InvalidParameterValueException("Account " + caller + " can't access project id=" + projectId);
|
throw new InvalidParameterValueException("Account " + caller + " can't access project id=" + projectId);
|
||||||
}
|
}
|
||||||
@ -1636,7 +1678,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
if (isFeatured != null) {
|
if (isFeatured != null) {
|
||||||
updatedTemplate.setFeatured(isFeatured.booleanValue());
|
updatedTemplate.setFeatured(isFeatured.booleanValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isExtractable != null && caller.getType() == Account.ACCOUNT_TYPE_ADMIN) {//Only ROOT admins allowed to change this powerful attribute
|
if (isExtractable != null && caller.getType() == Account.ACCOUNT_TYPE_ADMIN) {//Only ROOT admins allowed to change this powerful attribute
|
||||||
updatedTemplate.setExtractable(isExtractable.booleanValue());
|
updatedTemplate.setExtractable(isExtractable.booleanValue());
|
||||||
}else if (isExtractable != null && caller.getType() != Account.ACCOUNT_TYPE_ADMIN) {
|
}else if (isExtractable != null && caller.getType() != Account.ACCOUNT_TYPE_ADMIN) {
|
||||||
@ -1686,15 +1728,15 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private String getRandomPrivateTemplateName() {
|
private String getRandomPrivateTemplateName() {
|
||||||
return UUID.randomUUID().toString();
|
return UUID.randomUUID().toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@DB
|
@DB
|
||||||
@ -1733,7 +1775,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
throw new CloudRuntimeException(
|
throw new CloudRuntimeException(
|
||||||
"Creating private Template need to specify snapshotId or volumeId");
|
"Creating private Template need to specify snapshotId or volumeId");
|
||||||
}
|
}
|
||||||
|
|
||||||
CommandResult result = null;
|
CommandResult result = null;
|
||||||
try {
|
try {
|
||||||
result = future.get();
|
result = future.get();
|
||||||
@ -1742,7 +1784,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
s_logger.debug("Failed to create template" + result.getResult());
|
s_logger.debug("Failed to create template" + result.getResult());
|
||||||
throw new CloudRuntimeException("Failed to create template" + result.getResult());
|
throw new CloudRuntimeException("Failed to create template" + result.getResult());
|
||||||
}
|
}
|
||||||
|
|
||||||
privateTemplate = this._tmpltDao.findById(templateId);
|
privateTemplate = this._tmpltDao.findById(templateId);
|
||||||
UsageEventVO usageEvent = new UsageEventVO(
|
UsageEventVO usageEvent = new UsageEventVO(
|
||||||
EventTypes.EVENT_TEMPLATE_CREATE,
|
EventTypes.EVENT_TEMPLATE_CREATE,
|
||||||
@ -1990,7 +2032,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Pair<String, String> getAbsoluteIsoPath(long templateId,
|
public Pair<String, String> getAbsoluteIsoPath(long templateId,
|
||||||
long dataCenterId) {
|
long dataCenterId) {
|
||||||
@ -2108,7 +2150,7 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
}
|
}
|
||||||
return hosts;
|
return hosts;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Long getTemplateSize(long templateId, long zoneId) {
|
public Long getTemplateSize(long templateId, long zoneId) {
|
||||||
SearchCriteria<VMTemplateHostVO> sc = HostTemplateStatesSearch.create();
|
SearchCriteria<VMTemplateHostVO> sc = HostTemplateStatesSearch.create();
|
||||||
@ -2145,4 +2187,24 @@ public class TemplateManagerImpl extends ManagerBase implements TemplateManager,
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// find image store where this template is located
|
||||||
|
@Override
|
||||||
|
public List<DataStore> getImageStoreByTemplate(long templateId, Long zoneId) {
|
||||||
|
// find all eligible image stores for this zone scope
|
||||||
|
List<DataStore> imageStores = this.dataStoreMgr.getImageStoresByScope(new ZoneScope(zoneId));
|
||||||
|
if ( imageStores == null || imageStores.size() == 0 ){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
List<DataStore> stores = new ArrayList<DataStore>();
|
||||||
|
for (DataStore store : imageStores){
|
||||||
|
// check if the template is stored there
|
||||||
|
List<TemplateDataStoreVO> storeTmpl = this._tmplStoreDao.listByTemplateStore(templateId, store.getId());
|
||||||
|
if ( storeTmpl != null && storeTmpl.size() > 0 ){
|
||||||
|
stores.add(store);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return stores;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -140,7 +140,7 @@ CREATE TABLE `cloud`.`template_store_ref` (
|
|||||||
INDEX `i_template_store_ref__template_id`(`template_id`)
|
INDEX `i_template_store_ref__template_id`(`template_id`)
|
||||||
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
|
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
|
||||||
|
|
||||||
ALTER TABLE `cloud`.`vm_template` ADD COLUMN `image_data_store_id` bigint unsigned;
|
-- ALTER TABLE `cloud`.`vm_template` ADD COLUMN `image_data_store_id` bigint unsigned;
|
||||||
|
|
||||||
-- Do we still need these columns? TODO, to delete them, remove FK constraints from snapshots table
|
-- Do we still need these columns? TODO, to delete them, remove FK constraints from snapshots table
|
||||||
-- ALTER TABLE `cloud`.`snapshots` DROP COLUMN `swift_id`;
|
-- ALTER TABLE `cloud`.`snapshots` DROP COLUMN `swift_id`;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user