Refactored detach iso command

This commit is contained in:
abhishek 2010-08-25 15:33:06 -07:00
parent 37f6e794d9
commit cf68dfb430
5 changed files with 241 additions and 143 deletions

View File

@ -18,30 +18,18 @@
package com.cloud.api.commands;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import com.cloud.api.BaseCmd;
import com.cloud.api.BaseAsyncCmd;
import com.cloud.api.Implementation;
import com.cloud.api.Parameter;
import com.cloud.api.ServerApiException;
import com.cloud.user.Account;
import com.cloud.utils.Pair;
import com.cloud.vm.UserVmVO;
public class DetachIsoCmd extends BaseCmd {
import com.cloud.api.BaseCmd.Manager;
@Implementation(method="detachIso", manager=Manager.TemplateManager)
public class DetachIsoCmd extends BaseAsyncCmd {
public static final Logger s_logger = Logger.getLogger(DetachIsoCmd.class.getName());
private static final String s_name = "detachisoresponse";
private static final List<Pair<Enum, Boolean>> s_properties = new ArrayList<Pair<Enum, Boolean>>();
static {
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.VIRTUAL_MACHINE_ID, Boolean.TRUE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.ACCOUNT_OBJ, Boolean.FALSE));
s_properties.add(new Pair<Enum, Boolean>(BaseCmd.Properties.USER_ID, Boolean.FALSE));
}
/////////////////////////////////////////////////////
//////////////// API parameters /////////////////////
@ -68,59 +56,61 @@ public class DetachIsoCmd extends BaseCmd {
public String getName() {
return s_name;
}
@Override
public List<Pair<Enum, Boolean>> getProperties() {
return s_properties;
}
@Override
public List<Pair<String, Object>> execute(Map<String, Object> params) {
Account account = (Account) params.get(BaseCmd.Properties.ACCOUNT_OBJ.getName());
Long userId = (Long) params.get(BaseCmd.Properties.USER_ID.getName());
Long vmId = (Long) params.get(BaseCmd.Properties.VIRTUAL_MACHINE_ID.getName());
// @Override
// public List<Pair<String, Object>> execute(Map<String, Object> params) {
// Account account = (Account) params.get(BaseCmd.Properties.ACCOUNT_OBJ.getName());
// Long userId = (Long) params.get(BaseCmd.Properties.USER_ID.getName());
// Long vmId = (Long) params.get(BaseCmd.Properties.VIRTUAL_MACHINE_ID.getName());
//
// // Verify input parameters
// UserVmVO vmInstanceCheck = getManagementServer().findUserVMInstanceById(vmId.longValue());
// if (vmInstanceCheck == null) {
// throw new ServerApiException (BaseCmd.VM_INVALID_PARAM_ERROR, "Unable to find a virtual machine with id " + vmId);
// }
//
// if (account != null) {
// if (!isAdmin(account.getType())) {
// if (account.getId().longValue() != vmInstanceCheck.getAccountId()) {
// throw new ServerApiException(BaseCmd.ACCOUNT_ERROR, "Unable to detach ISO from virtual machine " + vmInstanceCheck.getName() + " for this account");
// }
// } else if (!getManagementServer().isChildDomain(account.getDomainId(), vmInstanceCheck.getDomainId())) {
// throw new ServerApiException(BaseCmd.ACCOUNT_ERROR, "Unable to detach ISO from virtual machine " + vmInstanceCheck.getName() + ", permission denied.");
// }
// }
//
// // If command is executed via 8096 port, set userId to the id of System account (1)
// if (userId == null)
// userId = new Long(1);
//
// try {
// long jobId = getManagementServer().detachISOFromVMAsync(vmId.longValue(), userId);
//
// if (jobId == 0) {
// s_logger.warn("Unable to schedule async-job for AttachIsoCmd");
// } else {
// if(s_logger.isDebugEnabled())
// s_logger.debug("AttachIsoCmd has been accepted, job id: " + jobId);
// }
//
// List<Pair<String, Object>> returnValues = new ArrayList<Pair<String, Object>>();
// returnValues.add(new Pair<String, Object>(BaseCmd.Properties.JOB_ID.getName(), Long.valueOf(jobId)));
//
// return returnValues;
// } catch (ServerApiException apiEx) {
// s_logger.error("Exception detaching ISO", apiEx);
// throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to detach ISO: " + apiEx.getDescription());
// } catch (Exception ex) {
// s_logger.error("Exception detaching ISO", ex);
// throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to detach ISO: " + ex.getMessage());
// }
//
// }
// Verify input parameters
UserVmVO vmInstanceCheck = getManagementServer().findUserVMInstanceById(vmId.longValue());
if (vmInstanceCheck == null) {
throw new ServerApiException (BaseCmd.VM_INVALID_PARAM_ERROR, "Unable to find a virtual machine with id " + vmId);
}
if (account != null) {
if (!isAdmin(account.getType())) {
if (account.getId().longValue() != vmInstanceCheck.getAccountId()) {
throw new ServerApiException(BaseCmd.ACCOUNT_ERROR, "Unable to detach ISO from virtual machine " + vmInstanceCheck.getName() + " for this account");
}
} else if (!getManagementServer().isChildDomain(account.getDomainId(), vmInstanceCheck.getDomainId())) {
throw new ServerApiException(BaseCmd.ACCOUNT_ERROR, "Unable to detach ISO from virtual machine " + vmInstanceCheck.getName() + ", permission denied.");
}
}
// If command is executed via 8096 port, set userId to the id of System account (1)
if (userId == null)
userId = new Long(1);
try {
long jobId = getManagementServer().detachISOFromVMAsync(vmId.longValue(), userId);
if (jobId == 0) {
s_logger.warn("Unable to schedule async-job for AttachIsoCmd");
} else {
if(s_logger.isDebugEnabled())
s_logger.debug("AttachIsoCmd has been accepted, job id: " + jobId);
}
List<Pair<String, Object>> returnValues = new ArrayList<Pair<String, Object>>();
returnValues.add(new Pair<String, Object>(BaseCmd.Properties.JOB_ID.getName(), Long.valueOf(jobId)));
return returnValues;
} catch (ServerApiException apiEx) {
s_logger.error("Exception detaching ISO", apiEx);
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to detach ISO: " + apiEx.getDescription());
} catch (Exception ex) {
s_logger.error("Exception detaching ISO", ex);
throw new ServerApiException(BaseCmd.INTERNAL_ERROR, "Failed to detach ISO: " + ex.getMessage());
}
}
@Override
public String getResponse() {
// TODO Auto-generated method stub
return null;
}
}

View File

@ -646,7 +646,7 @@ public interface ManagementServer {
*/
boolean attachISOToVM(long vmId, long userId, long isoId, boolean attach, long startEventId);
long attachISOToVMAsync(long vmId, long userId, long isoId) throws InvalidParameterValueException;
long detachISOFromVMAsync(long vmId, long userId) throws InvalidParameterValueException;
// long detachISOFromVMAsync(long vmId, long userId) throws InvalidParameterValueException;
/**
* Creates and starts a new Virtual Machine.
@ -1126,8 +1126,8 @@ public interface ManagementServer {
* @param zoneId
* @return true if success
*/
boolean deleteTemplate(long userId, long templateId, Long zoneId, long startEventId) throws InternalErrorException;
long deleteTemplateAsync(long userId, long templateId, Long zoneId) throws InvalidParameterValueException;
// boolean deleteTemplate(long userId, long templateId, Long zoneId, long startEventId) throws InternalErrorException;
// long deleteTemplateAsync(long userId, long templateId, Long zoneId) throws InvalidParameterValueException;
/**
* Copies a template from one secondary storage server to another

View File

@ -2215,35 +2215,35 @@ public class ManagementServerImpl implements ManagementServer {
return _asyncMgr.submitAsyncJob(job, true);
}
@Override
public long detachISOFromVMAsync(long vmId, long userId) throws InvalidParameterValueException {
UserVm userVM = _userVmDao.findById(vmId);
if (userVM == null) {
throw new InvalidParameterValueException("Please specify a valid VM.");
}
Long isoId = userVM.getIsoId();
if (isoId == null) {
throw new InvalidParameterValueException("The specified VM has no ISO attached to it.");
}
State vmState = userVM.getState();
if (vmState != State.Running && vmState != State.Stopped) {
throw new InvalidParameterValueException("Please specify a VM that is either Stopped or Running.");
}
long eventId = EventUtils.saveScheduledEvent(userId, userVM.getAccountId(), EventTypes.EVENT_ISO_DETACH, "detaching ISO: "+isoId+" from Vm: "+vmId);
AttachISOParam param = new AttachISOParam(vmId, userId, isoId.longValue(), false);
param.setEventId(eventId);
Gson gson = GsonHelper.getBuilder().create();
AsyncJobVO job = new AsyncJobVO();
job.setUserId(UserContext.current().getUserId());
job.setAccountId(userVM.getAccountId());
job.setCmd("AttachISO");
job.setCmdInfo(gson.toJson(param));
return _asyncMgr.submitAsyncJob(job, true);
}
// @Override
// public long detachISOFromVMAsync(long vmId, long userId) throws InvalidParameterValueException {
// UserVm userVM = _userVmDao.findById(vmId);
// if (userVM == null) {
// throw new InvalidParameterValueException("Please specify a valid VM.");
// }
//
// Long isoId = userVM.getIsoId();
// if (isoId == null) {
// throw new InvalidParameterValueException("The specified VM has no ISO attached to it.");
// }
//
// State vmState = userVM.getState();
// if (vmState != State.Running && vmState != State.Stopped) {
// throw new InvalidParameterValueException("Please specify a VM that is either Stopped or Running.");
// }
//
// long eventId = EventUtils.saveScheduledEvent(userId, userVM.getAccountId(), EventTypes.EVENT_ISO_DETACH, "detaching ISO: "+isoId+" from Vm: "+vmId);
// AttachISOParam param = new AttachISOParam(vmId, userId, isoId.longValue(), false);
// param.setEventId(eventId);
// Gson gson = GsonHelper.getBuilder().create();
//
// AsyncJobVO job = new AsyncJobVO();
// job.setUserId(UserContext.current().getUserId());
// job.setAccountId(userVM.getAccountId());
// job.setCmd("AttachISO");
// job.setCmdInfo(gson.toJson(param));
// return _asyncMgr.submitAsyncJob(job, true);
// }
// @Override
// public long resetVMPasswordAsync(long userId, long vmId, String password) {
@ -4774,47 +4774,47 @@ public class ManagementServerImpl implements ManagementServer {
return _templateDao.update(id, template);
}
@Override
public boolean deleteTemplate(long userId, long templateId, Long zoneId, long startEventId) throws InternalErrorException {
return _tmpltMgr.delete(userId, templateId, zoneId, startEventId);
}
// @Override
// public boolean deleteTemplate(long userId, long templateId, Long zoneId, long startEventId) throws InternalErrorException {
// return _tmpltMgr.delete(userId, templateId, zoneId, startEventId);
// }
@Override
public long deleteTemplateAsync(long userId, long templateId, Long zoneId) throws InvalidParameterValueException {
UserVO user = _userDao.findById(userId);
if (user == null) {
throw new InvalidParameterValueException("Please specify a valid user.");
}
VMTemplateVO template = _templateDao.findById(templateId);
if (template == null) {
throw new InvalidParameterValueException("Please specify a valid template.");
}
if (template.getFormat() == ImageFormat.ISO) {
throw new InvalidParameterValueException("Please specify a valid template.");
}
if (template.getUniqueName().equals("routing")) {
throw new InvalidParameterValueException("The DomR template cannot be deleted.");
}
if (zoneId != null && (_hostDao.findSecondaryStorageHost(zoneId) == null)) {
throw new InvalidParameterValueException("Failed to find a secondary storage host in the specified zone.");
}
DeleteTemplateParam param = new DeleteTemplateParam(userId, templateId, zoneId, 0);
Gson gson = GsonHelper.getBuilder().create();
AsyncJobVO job = new AsyncJobVO();
job.setUserId(UserContext.current().getUserId());
job.setAccountId(template.getAccountId());
job.setCmd("DeleteTemplate");
job.setCmdInfo(gson.toJson(param));
job.setCmdOriginator(DeleteTemplateCmd.getStaticName());
return _asyncMgr.submitAsyncJob(job);
}
// @Override
// public long deleteTemplateAsync(long userId, long templateId, Long zoneId) throws InvalidParameterValueException {
// UserVO user = _userDao.findById(userId);
// if (user == null) {
// throw new InvalidParameterValueException("Please specify a valid user.");
// }
//
// VMTemplateVO template = _templateDao.findById(templateId);
// if (template == null) {
// throw new InvalidParameterValueException("Please specify a valid template.");
// }
//
// if (template.getFormat() == ImageFormat.ISO) {
// throw new InvalidParameterValueException("Please specify a valid template.");
// }
//
// if (template.getUniqueName().equals("routing")) {
// throw new InvalidParameterValueException("The DomR template cannot be deleted.");
// }
//
// if (zoneId != null && (_hostDao.findSecondaryStorageHost(zoneId) == null)) {
// throw new InvalidParameterValueException("Failed to find a secondary storage host in the specified zone.");
// }
//
// DeleteTemplateParam param = new DeleteTemplateParam(userId, templateId, zoneId, 0);
// Gson gson = GsonHelper.getBuilder().create();
//
// AsyncJobVO job = new AsyncJobVO();
// job.setUserId(UserContext.current().getUserId());
// job.setAccountId(template.getAccountId());
// job.setCmd("DeleteTemplate");
// job.setCmdInfo(gson.toJson(param));
// job.setCmdOriginator(DeleteTemplateCmd.getStaticName());
//
// return _asyncMgr.submitAsyncJob(job);
// }
@Override
public boolean copyTemplate(long userId, long templateId, long sourceZoneId, long destZoneId, long startEventId) throws InternalErrorException {

View File

@ -22,6 +22,7 @@ import java.net.URISyntaxException;
import java.util.List;
import com.cloud.api.commands.CreateTemplateCmd;
import com.cloud.api.commands.DetachIsoCmd;
import com.cloud.api.commands.RegisterIsoCmd;
import com.cloud.api.commands.RegisterTemplateCmd;
import com.cloud.exception.InternalErrorException;
@ -119,6 +120,7 @@ public interface TemplateManager extends Manager {
*/
boolean delete(long userId, long templateId, Long zoneId, long startEventId) throws InternalErrorException;
boolean detachIso(DetachIsoCmd cmd) throws InternalErrorException, InvalidParameterValueException;
/**
* Lists templates in the specified storage pool that are not being used by any VM.
* @param pool

View File

@ -23,13 +23,14 @@ import java.net.URI;
import java.net.URISyntaxException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.ejb.Local;
import javax.naming.ConfigurationException;
import org.GNOME.Accessibility._ValueStub;
import org.GNOME.Bonobo._UnknownStub;
import org.apache.log4j.Logger;
import com.cloud.agent.api.Answer;
@ -39,14 +40,17 @@ import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
import com.cloud.agent.manager.AgentManager;
import com.cloud.api.BaseCmd;
import com.cloud.api.ServerApiException;
import com.cloud.api.commands.DetachIsoCmd;
import com.cloud.api.commands.RegisterIsoCmd;
import com.cloud.api.commands.RegisterTemplateCmd;
import com.cloud.configuration.ResourceCount.ResourceType;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.dc.DataCenterVO;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.domain.dao.DomainDao;
import com.cloud.event.EventState;
import com.cloud.event.EventTypes;
import com.cloud.event.EventUtils;
import com.cloud.event.EventVO;
import com.cloud.event.dao.EventDao;
import com.cloud.exception.InternalErrorException;
@ -85,6 +89,7 @@ import com.cloud.user.UserVO;
import com.cloud.user.dao.AccountDao;
import com.cloud.user.dao.UserAccountDao;
import com.cloud.user.dao.UserDao;
import com.cloud.uservm.UserVm;
import com.cloud.utils.EnumUtils;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.component.ComponentLocator;
@ -94,7 +99,11 @@ import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.State;
import com.cloud.vm.UserVmManager;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.dao.UserVmDao;
import com.cloud.vm.dao.VMInstanceDao;
@Local(value=TemplateManager.class)
@ -117,10 +126,13 @@ public class TemplateManagerImpl implements TemplateManager {
@Inject AccountManager _accountMgr;
@Inject HostDao _hostDao;
@Inject DataCenterDao _dcDao;
@Inject UserVmDao _userVmDao;
@Inject VolumeDao _volumeDao;
@Inject SnapshotDao _snapshotDao;
@Inject DomainDao _domainDao;
long _routerTemplateId = -1;
@Inject StorageManager _storageMgr;
@Inject UserVmManager _vmMgr;
@Inject ConfigurationDao _configDao;
protected SearchBuilder<VMTemplateHostVO> HostTemplateStatesSearch;
@ -868,4 +880,98 @@ public class TemplateManagerImpl implements TemplateManager {
return true;
}
@Override
public boolean detachIso(DetachIsoCmd cmd) throws InternalErrorException, InvalidParameterValueException {
Account account = (Account) UserContext.current().getAccountObject();
Long userId = UserContext.current().getUserId();
Long vmId = cmd.getVirtualMachineId();
// Verify input parameters
UserVmVO vmInstanceCheck = _userVmDao.findById(vmId.longValue());
if (vmInstanceCheck == null) {
throw new ServerApiException (BaseCmd.VM_INVALID_PARAM_ERROR, "Unable to find a virtual machine with id " + vmId);
}
userId = accountAndUserValidation(account, userId, vmInstanceCheck);
UserVm userVM = _userVmDao.findById(vmId);
if (userVM == null) {
throw new InvalidParameterValueException("Please specify a valid VM.");
}
Long isoId = userVM.getIsoId();
if (isoId == null) {
throw new InvalidParameterValueException("The specified VM has no ISO attached to it.");
}
State vmState = userVM.getState();
if (vmState != State.Running && vmState != State.Stopped) {
throw new InvalidParameterValueException("Please specify a VM that is either Stopped or Running.");
}
return attachISOToVM(vmId, userId, isoId, false); //attach=false => detach
}
private boolean attachISOToVM(long vmId, long userId, long isoId, boolean attach) {
UserVmVO vm = _userVmDao.findById(vmId);
VMTemplateVO iso = _tmpltDao.findById(isoId);
long startEventId = 0;
if(attach){
startEventId = EventUtils.saveStartedEvent(userId, vm.getAccountId(), EventTypes.EVENT_ISO_ATTACH, "Attaching ISO: "+isoId+" to Vm: "+vmId, startEventId);
} else {
startEventId = EventUtils.saveStartedEvent(userId, vm.getAccountId(), EventTypes.EVENT_ISO_DETACH, "Detaching ISO: "+isoId+" from Vm: "+vmId, startEventId);
}
boolean success = _vmMgr.attachISOToVM(vmId, isoId, attach);
if (success) {
if (attach) {
vm.setIsoId(iso.getId().longValue());
} else {
vm.setIsoId(null);
}
_userVmDao.update(vmId, vm);
if (attach) {
EventUtils.saveEvent(userId, vm.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_ISO_ATTACH, "Successfully attached ISO: " + iso.getName() + " to VM with ID: " + vmId,
null, startEventId);
} else {
EventUtils.saveEvent(userId, vm.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_ISO_DETACH, "Successfully detached ISO from VM with ID: " + vmId, null, startEventId);
}
} else {
if (attach) {
EventUtils.saveEvent(userId, vm.getAccountId(), EventVO.LEVEL_ERROR, EventTypes.EVENT_ISO_ATTACH, "Failed to attach ISO: " + iso.getName() + " to VM with ID: " + vmId, null, startEventId);
} else {
EventUtils.saveEvent(userId, vm.getAccountId(), EventVO.LEVEL_ERROR, EventTypes.EVENT_ISO_DETACH, "Failed to detach ISO from VM with ID: " + vmId, null, startEventId);
}
}
return success;
}
private Long accountAndUserValidation(Account account, Long userId,
UserVmVO vmInstanceCheck) {
if (account != null) {
if (!isAdmin(account.getType())) {
if (account.getId().longValue() != vmInstanceCheck.getAccountId()) {
throw new ServerApiException(BaseCmd.ACCOUNT_ERROR, "Unable to detach ISO from virtual machine " + vmInstanceCheck.getName() + " for this account");
}
} else if (!_domainDao.isChildDomain(account.getDomainId(), vmInstanceCheck.getDomainId())) {
throw new ServerApiException(BaseCmd.ACCOUNT_ERROR, "Unable to detach ISO from virtual machine " + vmInstanceCheck.getName() + ", permission denied.");
}
}
// If command is executed via 8096 port, set userId to the id of System account (1)
if (userId == null)
userId = new Long(1);
return userId;
}
private static boolean isAdmin(short accountType) {
return ((accountType == Account.ACCOUNT_TYPE_ADMIN) ||
(accountType == Account.ACCOUNT_TYPE_DOMAIN_ADMIN) ||
(accountType == Account.ACCOUNT_TYPE_READ_ONLY_ADMIN));
}
}