consolidated all of the vm destroy, cleanup and account cleanup.

This commit is contained in:
Alex Huang 2010-12-29 15:15:21 -08:00
parent e7749afdfe
commit da4ed648ac
16 changed files with 287 additions and 434 deletions

View File

@ -303,11 +303,6 @@ public class AgentBasedConsoleProxyManager implements ConsoleProxyManager, Virtu
return VirtualMachineName.getConsoleProxyId(vmName);
}
@Override
public boolean destroy(ConsoleProxyVO vm) throws AgentUnavailableException {
return false;
}
@Override
public ConsoleProxyVO get(long id) {
return null;

View File

@ -90,8 +90,8 @@ import com.cloud.exception.ResourceUnavailableException;
import com.cloud.exception.StorageUnavailableException;
import com.cloud.ha.HighAvailabilityManager;
import com.cloud.host.Host;
import com.cloud.host.HostVO;
import com.cloud.host.Host.Type;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.info.ConsoleProxyConnectionInfo;
import com.cloud.info.ConsoleProxyInfo;
@ -115,9 +115,9 @@ import com.cloud.servlet.ConsoleProxyServlet;
import com.cloud.storage.StorageManager;
import com.cloud.storage.StoragePoolVO;
import com.cloud.storage.VMTemplateHostVO;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.VolumeVO;
import com.cloud.storage.VMTemplateStorageResourceAssoc.Status;
import com.cloud.storage.dao.GuestOSDao;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VMTemplateHostDao;
@ -1545,11 +1545,6 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, ConsoleProx
}
}
@Override
public boolean destroy(ConsoleProxyVO proxy) throws AgentUnavailableException {
return destroyProxy(proxy.getId());
}
@Override
@DB
public boolean destroyProxy(long vmId) {
@ -1846,8 +1841,9 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, ConsoleProx
}
value = configs.get(Config.ConsoleProxyDisableRpFilter.key());
if(value != null && value.equalsIgnoreCase("true"))
_disable_rp_filter = true;
if(value != null && value.equalsIgnoreCase("true")) {
_disable_rp_filter = true;
}
value = configs.get("system.vm.use.local.storage");
if (value != null && value.equalsIgnoreCase("true")) {
@ -1952,8 +1948,9 @@ public class ConsoleProxyManagerImpl implements ConsoleProxyManager, ConsoleProx
buf.append(" pod=").append(dest.getPod().getId());
buf.append(" guid=Proxy.").append(profile.getId());
buf.append(" proxy_vm=").append(profile.getId());
if(_disable_rp_filter)
if(_disable_rp_filter) {
buf.append(" disable_rp_filter=true");
}
boolean externalDhcp = false;
String externalDhcpStr = _configDao.getValue("direct.attach.network.externalIpAllocator.enabled");

View File

@ -60,6 +60,7 @@ import com.cloud.server.ManagementServer;
import com.cloud.storage.StorageManager;
import com.cloud.storage.dao.GuestOSCategoryDao;
import com.cloud.storage.dao.GuestOSDao;
import com.cloud.user.AccountManager;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.component.Adapters;
import com.cloud.utils.component.ComponentLocator;
@ -124,7 +125,9 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager {
@Inject DataCenterDao _dcDao;
@Inject HostPodDao _podDao;
long _serverId;
@Inject(adapter=Investigator.class)
Adapters<Investigator> _investigators;
@Inject(adapter=FenceBuilder.class)
Adapters<FenceBuilder> _fenceBuilders;
@Inject AgentManager _agentMgr;
@Inject AlertManager _alertMgr;
@ -132,6 +135,7 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager {
@Inject GuestOSDao _guestOSDao;
@Inject GuestOSCategoryDao _guestOSCategoryDao;
@Inject VirtualMachineManager _itMgr;
@Inject AccountManager _accountMgr;
String _instance;
ScheduledExecutorService _executor;
@ -833,19 +837,14 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager {
}
if (vm.getHostId() != null) {
Command cmd = mgr.cleanup(vm, null);
Answer ans = _agentMgr.send(work.getHostId(), cmd);
if (ans.getResult()) {
mgr.completeStopCommand(vm);
if (mgr.destroy(vm)) {
s_logger.info("Successfully stopped " + vm.toString());
return null;
}
}
s_logger.debug("Stop for " + vm.toString() + " was unsuccessful. Detail: " + ans.getDetails());
if (_itMgr.destroy(vm, _accountMgr.getSystemUser(), _accountMgr.getSystemAccount())) {
s_logger.info("Successfully destroy " + vm);
return null;
}
s_logger.debug("Stop for " + vm + " was unsuccessful.");
} else {
if (s_logger.isDebugEnabled()) {
s_logger.debug(vm.toString() + " has already been stopped");
s_logger.debug(vm + " has already been stopped");
}
return null;
}
@ -853,7 +852,9 @@ public class HighAvailabilityManagerImpl implements HighAvailabilityManager {
s_logger.debug("Agnet is not available" + e.getMessage());
} catch (OperationTimedoutException e) {
s_logger.debug("operation timed out: " + e.getMessage());
}
} catch (ConcurrentOperationException e) {
s_logger.debug("concurrent operation: " + e.getMessage());
}
work.setTimesTried(work.getTimesTried() + 1);
return (System.currentTimeMillis() >> 10) + _stopRetryInterval;

View File

@ -117,7 +117,7 @@ public interface NetworkManager extends NetworkService {
void prepare(VirtualMachineProfile<? extends VMInstanceVO> profile, DeployDestination dest, ReservationContext context) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException;
void release(VirtualMachineProfile<? extends VMInstanceVO> vmProfile);
void deallocate(VirtualMachineProfile<? extends VMInstanceVO> vm);
void cleanupNics(VirtualMachineProfile<? extends VMInstanceVO> vm);
List<? extends Nic> getNics (VirtualMachine vm);

View File

@ -1276,7 +1276,7 @@ public class NetworkManagerImpl implements NetworkManager, NetworkService, Manag
}
@Override
public void deallocate(VirtualMachineProfile<? extends VMInstanceVO> vm) {
public void cleanupNics(VirtualMachineProfile<? extends VMInstanceVO> vm) {
List<NicVO> nics = _nicDao.listBy(vm.getId());
for (NicVO nic : nics) {
nic.setState(Nic.State.Deallocating);

View File

@ -75,17 +75,17 @@ public class DhcpElement extends AdapterBase implements NetworkElement{
}
@Override
public boolean implement(Network guestConfig, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws ResourceUnavailableException, ConcurrentOperationException, InsufficientCapacityException {
public boolean implement(Network network, NetworkOffering offering, DeployDestination dest, ReservationContext context) throws ResourceUnavailableException, ConcurrentOperationException, InsufficientCapacityException {
if (!canHandle(offering.getGuestIpType(), dest)) {
return false;
}
_routerMgr.deployDhcp(guestConfig, dest, context.getAccount());
_routerMgr.deployDhcp(network, dest, context.getAccount());
return true;
}
@Override
public boolean prepare(Network config, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException {
if (canHandle(config.getGuestType(), dest)) {
public boolean prepare(Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm, DeployDestination dest, ReservationContext context) throws ConcurrentOperationException, InsufficientCapacityException, ResourceUnavailableException {
if (canHandle(network.getGuestType(), dest)) {
if (vm.getType() != VirtualMachine.Type.User) {
return false;
@ -94,20 +94,20 @@ public class DhcpElement extends AdapterBase implements NetworkElement{
@SuppressWarnings("unchecked")
VirtualMachineProfile<UserVm> uservm = (VirtualMachineProfile<UserVm>)vm;
return _routerMgr.addVirtualMachineIntoNetwork(config, nic, uservm, dest, context, true) != null;
return _routerMgr.addVirtualMachineIntoNetwork(network, nic, uservm, dest, context, true) != null;
} else {
return false;
}
}
@Override
public boolean release(Network config, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm, ReservationContext context) {
public boolean release(Network network, NicProfile nic, VirtualMachineProfile<? extends VirtualMachine> vm, ReservationContext context) {
return true;
}
@Override
public boolean shutdown(Network config, ReservationContext context) throws ConcurrentOperationException {
DomainRouterVO router = _routerDao.findByNetworkConfiguration(config.getId());
public boolean shutdown(Network network, ReservationContext context) throws ConcurrentOperationException {
DomainRouterVO router = _routerDao.findByNetworkConfiguration(network.getId());
if (router == null) {
return true;
}
@ -115,7 +115,7 @@ public class DhcpElement extends AdapterBase implements NetworkElement{
}
@Override
public boolean applyRules(Network config, List<? extends FirewallRule> rules) throws ResourceUnavailableException {
public boolean applyRules(Network network, List<? extends FirewallRule> rules) throws ResourceUnavailableException {
return false;
}

View File

@ -315,11 +315,6 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
return _routerDao.findByPublicIpAddress(publicIpAddress);
}
@Override
public boolean destroy(DomainRouterVO router) {
return destroyRouter(router.getId());
}
@Override
public boolean sendSshKeysToHost(Long hostId, String pubKey, String prvKey) {
ModifySshKeysCommand cmd = new ModifySshKeysCommand(pubKey, prvKey);

View File

@ -331,7 +331,6 @@ public class ManagementServerImpl implements ManagementServer {
private final UploadDao _uploadDao;
private final CertificateDao _certDao;
private final ScheduledExecutorService _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("AccountChecker"));
private final ScheduledExecutorService _eventExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("EventChecker"));
private final StatsCollector _statsCollector;
@ -344,8 +343,6 @@ public class ManagementServerImpl implements ManagementServer {
private final int _proxyRamSize;
private final int _ssRamSize;
private boolean _useNewNetworking = false;
private final Map<String, Boolean> _availableIdsMap;
private boolean _isHypervisorSnapshotCapable = false;
@ -431,7 +428,6 @@ public class ManagementServerImpl implements ManagementServer {
_ssRamSize = NumbersUtil.parseInt(_configs.get("secstorage.ram.size"), SecondaryStorageVmManager.DEFAULT_SS_VM_RAMSIZE);
_statsCollector = StatsCollector.getInstance(_configs);
_executor.scheduleAtFixedRate(new AccountCleanupTask(), cleanup, cleanup, TimeUnit.SECONDS);
_purgeDelay = NumbersUtil.parseInt(_configs.get("event.purge.delay"), 0);
if(_purgeDelay != 0){
@ -443,7 +439,6 @@ public class ManagementServerImpl implements ManagementServer {
for (String id: availableIds) {
_availableIdsMap.put(id, true);
}
_useNewNetworking = Boolean.parseBoolean(_configs.get("use.new.networking"));
}
protected Map<String, String> getConfigs() {
@ -3222,7 +3217,7 @@ public class ManagementServerImpl implements ManagementServer {
sc.addAnd("domainId", SearchCriteria.Op.EQ, domainId);
List<AccountVO> accounts = _accountDao.search(sc, null);
for (AccountVO account : accounts) {
success = (success && _accountMgr.deleteAccountInternal(account.getAccountId()));
success = (success && _accountMgr.cleanupAccount(account, UserContext.current().getCallerUserId(), UserContext.current().getCaller()));
String description = "Account:" + account.getAccountId();
if(success){
EventUtils.saveEvent(User.UID_SYSTEM, account.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_ACCOUNT_DELETE, "Successfully deleted " +description);
@ -3880,7 +3875,7 @@ public class ManagementServerImpl implements ManagementServer {
for (AccountVO account : accounts) {
s_logger.debug("Cleaning up " + account.getId());
try {
_accountMgr.deleteAccount(account);
_accountMgr.cleanupAccount(account, _accountMgr.getSystemUser().getId(), _accountMgr.getSystemAccount());
} catch (Exception e) {
s_logger.error("Skipping due to error on account " + account.getId(), e);
}
@ -4176,23 +4171,7 @@ public class ManagementServerImpl implements ManagementServer {
@Override
public VirtualMachine startSystemVM(StartSystemVMCmd cmd) {
if (_useNewNetworking) {
return startSystemVm(cmd.getId());
}
//verify input
Long id = cmd.getId();
VMInstanceVO systemVm = _vmInstanceDao.findByIdTypes(id, VirtualMachine.Type.ConsoleProxy, VirtualMachine.Type.SecondaryStorageVm);
if (systemVm == null) {
throw new ServerApiException (BaseCmd.PARAM_ERROR, "unable to find a system vm with id " + id);
}
if (systemVm.getType().equals(VirtualMachine.Type.ConsoleProxy)){
return startConsoleProxy(id);
} else {
return startSecondaryStorageVm(id);
}
return startSystemVm(cmd.getId());
}
@Override

View File

@ -62,7 +62,6 @@ import com.cloud.dc.dao.DataCenterDao;
import com.cloud.dc.dao.HostPodDao;
import com.cloud.deploy.DataCenterDeployment;
import com.cloud.deploy.DeployDestination;
import com.cloud.event.Event;
import com.cloud.event.EventTypes;
import com.cloud.event.EventUtils;
import com.cloud.event.EventVO;
@ -125,7 +124,6 @@ import com.cloud.utils.net.NfsUtils;
import com.cloud.vm.NicProfile;
import com.cloud.vm.NicVO;
import com.cloud.vm.ReservationContext;
import com.cloud.vm.SecondaryStorageVm;
import com.cloud.vm.SecondaryStorageVmVO;
import com.cloud.vm.State;
import com.cloud.vm.VirtualMachine;
@ -1103,12 +1101,6 @@ public class SecondaryStorageManagerImpl implements SecondaryStorageVmManager, V
}
}
@Override
public boolean destroy(SecondaryStorageVmVO secStorageVm)
throws AgentUnavailableException {
return destroySecStorageVm(secStorageVm.getId());
}
@Override
@DB
public boolean destroySecStorageVm(long vmId) {

View File

@ -29,13 +29,12 @@ import com.cloud.domain.Domain;
import com.cloud.domain.DomainVO;
import com.cloud.exception.PermissionDeniedException;
import com.cloud.server.Criteria;
import com.cloud.utils.component.Manager;
/**
* AccountManager includes logic that deals with accounts, domains, and users.
*
*/
public interface AccountManager extends Manager {
public interface AccountManager extends AccountService {
/**
* Finds all ISOs that are usable for a user. This includes ISOs usable for the user's account and for all of the account's parent domains.
@ -106,14 +105,15 @@ public interface AccountManager extends Manager {
*/
boolean disableAccount(long accountId);
boolean deleteAccount(AccountVO account);
boolean deleteAccount(AccountVO account, long callerUserId, Account caller);
void checkAccess(Account account, Domain domain) throws PermissionDeniedException;
void checkAccess(Account account, ControlledEntity... entities) throws PermissionDeniedException;
boolean deleteAccountInternal(long accountId);
boolean cleanupAccount(AccountVO account, long callerUserId, Account caller);
UserVO createUser(CreateUserCmd cmd);
@Override
UserVO createUser(CreateUserCmd cmd);
}

View File

@ -22,6 +22,9 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import javax.ejb.Local;
import javax.naming.ConfigurationException;
@ -45,9 +48,11 @@ import com.cloud.api.commands.LockUserCmd;
import com.cloud.api.commands.UpdateAccountCmd;
import com.cloud.api.commands.UpdateResourceLimitCmd;
import com.cloud.api.commands.UpdateUserCmd;
import com.cloud.configuration.Config;
import com.cloud.configuration.ConfigurationManager;
import com.cloud.configuration.ResourceCount.ResourceType;
import com.cloud.configuration.ResourceLimitVO;
import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.configuration.dao.ResourceCountDao;
import com.cloud.configuration.dao.ResourceLimitDao;
import com.cloud.dc.PodVlanMapVO;
@ -83,13 +88,18 @@ import com.cloud.user.Account.State;
import com.cloud.user.dao.AccountDao;
import com.cloud.user.dao.UserAccountDao;
import com.cloud.user.dao.UserDao;
import com.cloud.utils.NumbersUtil;
import com.cloud.utils.Pair;
import com.cloud.utils.component.Adapters;
import com.cloud.utils.component.ComponentLocator;
import com.cloud.utils.component.Inject;
import com.cloud.utils.component.Manager;
import com.cloud.utils.concurrency.NamedThreadFactory;
import com.cloud.utils.db.Filter;
import com.cloud.utils.db.GlobalLock;
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.DomainRouterVO;
import com.cloud.vm.InstanceGroupVO;
@ -100,7 +110,7 @@ import com.cloud.vm.dao.InstanceGroupDao;
import com.cloud.vm.dao.UserVmDao;
@Local(value={AccountManager.class, AccountService.class})
public class AccountManagerImpl implements AccountManager, AccountService {
public class AccountManagerImpl implements AccountManager, AccountService, Manager {
public static final Logger s_logger = Logger.getLogger(AccountManagerImpl.class);
private String _name;
@ -130,12 +140,15 @@ public class AccountManagerImpl implements AccountManager, AccountService {
@Inject private ConfigurationManager _configMgr;
@Inject private VirtualNetworkApplianceManager _routerMgr;
private final ScheduledExecutorService _executor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("AccountChecker"));
private final GlobalLock m_resourceCountLock = GlobalLock.getInternLock("resource.count");
UserVO _systemUser;
AccountVO _systemAccount;
@Inject(adapter=SecurityChecker.class)
Adapters<SecurityChecker> _securityCheckers;
int _cleanupInterval;
@Override
public boolean configure(final String name, final Map<String, Object> params) throws ConfigurationException {
@ -150,6 +163,14 @@ public class AccountManagerImpl implements AccountManager, AccountService {
if (_systemUser == null) {
throw new ConfigurationException("Unable to find the system user using " + User.UID_SYSTEM);
}
ComponentLocator locator = ComponentLocator.getCurrentLocator();
ConfigurationDao configDao = locator.getDao(ConfigurationDao.class);
Map<String, String> configs = configDao.getConfiguration(params);
String value = configs.get(Config.AccountCleanupInterval.key());
_cleanupInterval = NumbersUtil.parseInt(value, 60 * 60 * 24); // 1 hour.
return true;
}
@ -165,6 +186,7 @@ public class AccountManagerImpl implements AccountManager, AccountService {
@Override
public boolean start() {
_executor.scheduleAtFixedRate(new AccountCleanupTask(), _cleanupInterval, _cleanupInterval, TimeUnit.SECONDS);
return true;
}
@ -752,31 +774,27 @@ public class AccountManagerImpl implements AccountManager, AccountService {
}
@Override
public boolean deleteAccountInternal(long accountId) {
boolean result = false;
public boolean deleteAccount(AccountVO account, long callerUserId, Account caller) {
long accountId = account.getId();
try {
List<UserVO> users = _userDao.listByAccount(accountId);
for(UserVO user : users){
//remove each user
_userDao.remove(user.getId());
}
result = _accountDao.remove(accountId);
if (!result) {
if (!_accountDao.remove(accountId)) {
s_logger.error("Unable to delete account " + accountId);
return false;
}
List<UserVO> users = _userDao.listByAccount(accountId);
for(UserVO user : users){
_userDao.remove(user.getId());
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("Remove account " + accountId);
}
AccountVO account = _accountDao.findByIdIncludingRemoved(accountId);
deleteAccount(account);
result = true;
return result;
cleanupAccount(account, callerUserId, caller);
return true;
} catch (Exception e) {
s_logger.error("exception deleting account: " + accountId, e);
return false;
@ -784,9 +802,8 @@ public class AccountManagerImpl implements AccountManager, AccountService {
}
@Override
public boolean deleteAccount(AccountVO account) {
public boolean cleanupAccount(AccountVO account, long callerUserId, Account caller) {
long accountId = account.getId();
long userId = 1L; // only admins can delete users, pass in userId 1 XXX: Shouldn't it be userId 2.
boolean accountCleanupNeeded = false;
try {
@ -813,13 +830,13 @@ public class AccountManagerImpl implements AccountManager, AccountService {
}
for (UserVmVO vm : vms) {
long startEventId = EventUtils.saveStartedEvent(userId, vm.getAccountId(), EventTypes.EVENT_VM_DESTROY, "Destroyed VM instance : " + vm.getName());
if (!_vmMgr.destroyVirtualMachine(userId, vm.getId())) {
long startEventId = EventUtils.saveStartedEvent(callerUserId, vm.getAccountId(), EventTypes.EVENT_VM_DESTROY, "Destroyed VM instance : " + vm.getName());
if (!_vmMgr.expunge(vm, callerUserId, caller)) {
s_logger.error("Unable to destroy vm: " + vm.getId());
accountCleanupNeeded = true;
EventUtils.saveEvent(userId, vm.getAccountId(), EventVO.LEVEL_ERROR, EventTypes.EVENT_VM_DESTROY, "Unable to destroy vm: " + vm.getId(), startEventId);
EventUtils.saveEvent(callerUserId, vm.getAccountId(), EventVO.LEVEL_ERROR, EventTypes.EVENT_VM_DESTROY, "Unable to destroy vm: " + vm.getId(), startEventId);
} else {
EventUtils.saveEvent(userId, vm.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_VM_DESTROY, "Successfully destroyed VM instance : " + vm.getName(), startEventId);
EventUtils.saveEvent(callerUserId, vm.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_VM_DESTROY, "Successfully destroyed VM instance : " + vm.getName(), startEventId);
}
}
@ -840,13 +857,13 @@ public class AccountManagerImpl implements AccountManager, AccountService {
boolean routersCleanedUp = true;
for (DomainRouterVO router : routers) {
long startEventId = EventUtils.saveStartedEvent(userId, router.getAccountId(), EventTypes.EVENT_ROUTER_DESTROY, "Starting to destroy router : " + router.getName());
long startEventId = EventUtils.saveStartedEvent(callerUserId, router.getAccountId(), EventTypes.EVENT_ROUTER_DESTROY, "Starting to destroy router : " + router.getName());
if (!_routerMgr.destroyRouter(router.getId())) {
s_logger.error("Unable to destroy router: " + router.getId());
routersCleanedUp = false;
EventUtils.saveEvent(userId, router.getAccountId(), EventVO.LEVEL_ERROR, EventTypes.EVENT_ROUTER_DESTROY, "Unable to destroy router: " + router.getName(), startEventId);
EventUtils.saveEvent(callerUserId, router.getAccountId(), EventVO.LEVEL_ERROR, EventTypes.EVENT_ROUTER_DESTROY, "Unable to destroy router: " + router.getName(), startEventId);
} else {
EventUtils.saveEvent(userId, router.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_ROUTER_DESTROY, "successfully destroyed router : " + router.getName(), startEventId);
EventUtils.saveEvent(callerUserId, router.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_ROUTER_DESTROY, "successfully destroyed router : " + router.getName(), startEventId);
}
}
@ -907,7 +924,7 @@ public class AccountManagerImpl implements AccountManager, AccountService {
boolean allTemplatesDeleted = true;
for (VMTemplateVO template : userTemplates) {
try {
allTemplatesDeleted = _tmpltMgr.delete(userId, template.getId(), null);
allTemplatesDeleted = _tmpltMgr.delete(callerUserId, template.getId(), null);
} catch (Exception e) {
s_logger.warn("Failed to delete template while removing account: " + template.getName() + " due to: " + e.getMessage());
allTemplatesDeleted = false;
@ -1336,12 +1353,16 @@ public class AccountManagerImpl implements AccountManager, AccountService {
@Override
//This method deletes the account
public boolean deleteUserAccount(DeleteAccountCmd cmd) {
UserContext ctx = UserContext.current();
long callerUserId = ctx.getCallerUserId();
Account caller = ctx.getCaller();
Long accountId = cmd.getId();
// If the user is a System user, return an error. We do not allow this
Account account = _accountDao.findById(accountId);
AccountVO account = _accountDao.findById(accountId);
if ((account != null) && (account.getId() == Account.ACCOUNT_ID_SYSTEM)) {
throw new InvalidParameterValueException("Account id : " + accountId + " is a system account, delete is not allowed");
throw new PermissionDeniedException("Account id : " + accountId + " is a system account, delete is not allowed");
}
if(account == null){
@ -1353,7 +1374,7 @@ public class AccountManagerImpl implements AccountManager, AccountService {
return true;
}
return deleteAccountInternal(accountId);
return deleteAccount(account, callerUserId, caller);
}
@ -1506,5 +1527,48 @@ public class AccountManagerImpl implements AccountManager, AccountService {
}
return success;
}
protected class AccountCleanupTask implements Runnable {
@Override
public void run() {
try {
GlobalLock lock = GlobalLock.getInternLock("AccountCleanup");
if (lock == null) {
s_logger.debug("Couldn't get the global lock");
return;
}
if (!lock.lock(30)) {
s_logger.debug("Couldn't lock the db");
return;
}
Transaction txn = null;
try {
txn = Transaction.open(Transaction.CLOUD_DB);
List<AccountVO> accounts = _accountDao.findCleanups();
s_logger.info("Found " + accounts.size() + " accounts to cleanup");
for (AccountVO account : accounts) {
s_logger.debug("Cleaning up " + account.getId());
try {
cleanupAccount(account, getSystemUser().getId(), getSystemAccount());
} catch (Exception e) {
s_logger.error("Skipping due to error on account " + account.getId(), e);
}
}
} catch (Exception e) {
s_logger.error("Exception ", e);
} finally {
if(txn != null) {
txn.close();
}
lock.unlock();
}
} catch (Exception e) {
s_logger.error("Exception ", e);
}
}
}
}

View File

@ -24,6 +24,7 @@ import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.exception.StorageUnavailableException;
import com.cloud.user.Account;
import com.cloud.uservm.UserVm;
import com.cloud.utils.exception.ExecutionException;
import com.cloud.vm.VirtualMachine.Event;
@ -48,9 +49,6 @@ public interface UserVmManager extends VirtualMachineGuru<UserVmVO>{
*/
UserVmVO getVirtualMachine(long vmId);
boolean destroyVirtualMachine(long userId, long vmId);
/**
* Attaches an ISO to the virtual CDROM device of the specified VM. Will eject any existing virtual CDROM if isoPath is null.
* @param vmId
@ -79,13 +77,6 @@ public interface UserVmManager extends VirtualMachineGuru<UserVmVO>{
*/
HashMap<Long, VmStatsEntry> getVirtualMachineStatistics(long hostId, String hostName, List<Long> vmIds);
/**
* Clean the network rules for the given VM
* @param userId
* @param instanceId the id of the instance for which the network rules should be cleaned
*/
void cleanNetworkRules(long userId, long instanceId);
/**
* Releases a guest IP address for a VM. If the VM is on a direct attached network, will also unassign the IP address.
* @param userVm
@ -102,4 +93,7 @@ public interface UserVmManager extends VirtualMachineGuru<UserVmVO>{
UserVm startUserVm(long vmId) throws StorageUnavailableException,
ConcurrentOperationException, ExecutionException, ResourceUnavailableException, InsufficientCapacityException;
boolean expunge(UserVmVO vm, long callerUserId, Account caller);
}

View File

@ -1005,50 +1005,6 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
_vmDao.update(userVm.getId(), userVm);
}
@Override @DB
public boolean destroyVirtualMachine(long userId, long vmId) {
UserVmVO vm = _vmDao.findById(vmId);
if (vm == null || vm.getState() == State.Destroyed || vm.getState() == State.Expunging || vm.getRemoved() != null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Unable to find vm or vm is destroyed: " + vmId);
}
return true;
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("Destroying vm " + vmId);
}
long startEventId = EventUtils.saveStartedEvent(userId, vm.getAccountId(), EventTypes.EVENT_VM_STOP, "stopping Vm with Id: "+vmId);
if (!stop(userId, vm)) {
s_logger.error("Unable to stop vm so we can't destroy it: " + vmId);
EventUtils.saveEvent(userId, vm.getAccountId(), EventVO.LEVEL_ERROR, EventTypes.EVENT_VM_STOP, "Error stopping VM instance : " + vmId, startEventId);
return false;
} else {
EventUtils.saveEvent(userId, vm.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_VM_STOP, "Successfully stopped VM instance : " + vmId, startEventId);
}
Transaction txn = Transaction.currentTxn();
txn.start();
if (!destroy(vm)) {
return false;
}
UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VM_DESTROY, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), vm.getName(), vm.getServiceOfferingId(), vm.getTemplateId(), null);
_usageEventDao.persist(usageEvent);
cleanNetworkRules(userId, vmId);
// Mark the VM's disks as destroyed
List<VolumeVO> volumes = _volsDao.findByInstance(vmId);
for (VolumeVO volume : volumes) {
_storageMgr.destroyVolume(volume);
}
txn.commit();
return true;
}
@Override @DB
public UserVm recoverVirtualMachine(RecoverVMCmd cmd) throws ResourceAllocationException, CloudRuntimeException {
@ -1206,7 +1162,7 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
@Override
public boolean start() {
_executor.scheduleWithFixedDelay(new ExpungeTask(this), _expungeInterval, _expungeInterval, TimeUnit.SECONDS);
_executor.scheduleWithFixedDelay(new ExpungeTask(), _expungeInterval, _expungeInterval, TimeUnit.SECONDS);
return true;
}
@ -1364,19 +1320,6 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
return stopped;
}
@Override @DB
public boolean destroy(UserVmVO vm) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Destroying vm " + vm.toString());
}
if (!_itMgr.stateTransitTo(vm, VirtualMachine.Event.DestroyRequested, vm.getHostId())) {
s_logger.debug("Unable to destroy the vm because it is not in the correct state: " + vm.toString());
return false;
}
return true;
}
@Override
public HostVO prepareForMigration(UserVmVO vm) throws StorageUnavailableException {
long vmId = vm.getId();
@ -1454,52 +1397,80 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
return true;
}
@DB
public void expunge() {
List<UserVmVO> vms = _vmDao.findDestroyedVms(new Date(System.currentTimeMillis() - ((long)_expungeDelay << 10)));
s_logger.info("Found " + vms.size() + " vms to expunge.");
for (UserVmVO vm : vms) {
long vmId = vm.getId();
releaseGuestIpAddress(vm);
vm.setGuestNetmask(null);
vm.setGuestMacAddress(null);
if (!_itMgr.stateTransitTo(vm, VirtualMachine.Event.ExpungeOperation, null)) {
s_logger.info("vm " + vmId + " is skipped because it is no longer in Destroyed or Error state");
continue;
}
@Override
public boolean expunge(UserVmVO vm, long callerUserId, Account caller) {
try {
if (!_itMgr.advanceExpunge(vm, _accountMgr.getSystemUser(), caller)) {
s_logger.info("Did not expunge " + vm);
return false;
}
long vmId = vm.getId();
//cleanup port forwarding rules
if (_rulesMgr.revokePortForwardingRule(vmId)) {
s_logger.debug("Port forwarding rules are removed successfully as a part of vm id=" + vmId + " expunge");
} else {
s_logger.warn("Fail to remove port forwarding rules as a part of vm id=" + vmId + " expunge");
}
//cleanup load balancer rules
if (_lbMgr.removeVmFromLoadBalancers(vmId)) {
s_logger.debug("LB rules are removed successfully as a part of vm id=" + vmId + " expunge");
} else {
s_logger.warn("Fail to remove lb rules as a part of vm id=" + vmId + " expunge");
}
_networkGroupMgr.removeInstanceFromGroups(vm.getId());
removeInstanceFromGroup(vm.getId());
_itMgr.remove(vm, _accountMgr.getSystemUser(), caller);
return true;
} catch (ResourceUnavailableException e) {
s_logger.warn("Unable to expunging " + vm, e);
return false;
} catch (OperationTimedoutException e) {
s_logger.warn("Operation time out on expunging " + vm, e);
return false;
} catch (ConcurrentOperationException e) {
s_logger.warn("Concurrent operations on expunging " + vm, e);
return false;
}
// long vmId = vm.getId();
// releaseGuestIpAddress(vm);
// vm.setGuestNetmask(null);
// vm.setGuestMacAddress(null);
// if (!_itMgr.stateTransitTo(vm, VirtualMachine.Event.ExpungeOperation, null)) {
// s_logger.info("vm " + vmId + " is skipped because it is no longer in Destroyed or Error state");
// continue;
// }
//
// List<VolumeVO> vols = null;
// try {
// vols = _volsDao.findByInstanceIdDestroyed(vmId);
// _storageMgr.destroy(vm, vols);
//
//
// //cleanup load balancer rules
// if (_lbMgr.removeVmFromLoadBalancers(vmId)) {
// s_logger.debug("LB rules are removed successfully as a part of vm id=" + vmId + " expunge");
// } else {
// s_logger.warn("Fail to remove lb rules as a part of vm id=" + vmId + " expunge");
// }
//
// _vmDao.remove(vm.getId());
// s_logger.debug("vm is destroyed");
// } catch (Exception e) {
// s_logger.info("VM " + vm +" expunge failed due to ", e);
// }
List<VolumeVO> vols = null;
try {
vols = _volsDao.findByInstanceIdDestroyed(vmId);
_storageMgr.destroy(vm, vols);
//cleanup port forwarding rules
if (_rulesMgr.revokePortForwardingRule(vmId)) {
s_logger.debug("Port forwarding rules are removed successfully as a part of vm id=" + vmId + " expunge");
} else {
s_logger.warn("Fail to remove port forwarding rules as a part of vm id=" + vmId + " expunge");
}
//cleanup load balancer rules
if (_lbMgr.removeVmFromLoadBalancers(vmId)) {
s_logger.debug("LB rules are removed successfully as a part of vm id=" + vmId + " expunge");
} else {
s_logger.warn("Fail to remove lb rules as a part of vm id=" + vmId + " expunge");
}
_vmDao.remove(vm.getId());
_networkGroupMgr.removeInstanceFromGroups(vm.getId());
removeInstanceFromGroup(vm.getId());
s_logger.debug("vm is destroyed");
} catch (Exception e) {
s_logger.info("VM " + vmId +" expunge failed due to " + e.getMessage());
}
}
List<VolumeVO> destroyedVolumes = _volsDao.findByDetachedDestroyed();
s_logger.info("Found " + destroyedVolumes.size() + " detached volumes to expunge.");
_storageMgr.destroy(null, destroyedVolumes);
// }
//
// List<VolumeVO> destroyedVolumes = _volsDao.findByDetachedDestroyed();
// s_logger.info("Found " + destroyedVolumes.size() + " detached volumes to expunge.");
// _storageMgr.destroy(null, destroyedVolumes);
}
@Override @DB
@ -1536,46 +1507,6 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
}
}
@Override
public void cleanNetworkRules(long userId, long instanceId) {
//FIXME UserVmVO vm = _vmDao.findById(instanceId);
// String guestIpAddr = vm.getGuestIpAddress();
// long accountId = vm.getAccountId();
//
// List<LoadBalancerVMMapVO> loadBalancerMappings = _loadBalancerVMMapDao.listByInstanceId(vm.getId());
// for (LoadBalancerVMMapVO loadBalancerMapping : loadBalancerMappings) {
// List<PortForwardingRuleVO> lbRules = _rulesDao.listByLoadBalancerId(loadBalancerMapping.getLoadBalancerId());
// PortForwardingRuleVO targetLbRule = null;
// for (PortForwardingRuleVO lbRule : lbRules) {
// if (lbRule.getDestinationIpAddress().equals(guestIpAddr)) {
// targetLbRule = lbRule;
// targetLbRule.setEnabled(false);
// break;
// }
// }
//
// if (targetLbRule != null) {
// String ipAddress = targetLbRule.getSourceIpAddress();
// DomainRouterVO router = _routerDao.findById(vm.getDomainRouterId());
// _networkMgr.updateFirewallRules(ipAddress, lbRules, router);
//
// // now that the rule has been disabled, delete it, also remove the mapping from the load balancer mapping table
// _rulesDao.remove(targetLbRule.getId());
// _loadBalancerVMMapDao.remove(loadBalancerMapping.getId());
//
// // save off the event for deleting the LB rule
// EventVO lbRuleEvent = new EventVO();
// lbRuleEvent.setUserId(userId);
// lbRuleEvent.setAccountId(accountId);
// lbRuleEvent.setType(EventTypes.EVENT_NET_RULE_DELETE);
// lbRuleEvent.setDescription("deleted load balancer rule [" + targetLbRule.getSourceIpAddress() + ":" + targetLbRule.getSourcePort() +
// "]->[" + targetLbRule.getDestinationIpAddress() + ":" + targetLbRule.getDestinationPort() + "]" + " " + targetLbRule.getAlgorithm());
// lbRuleEvent.setLevel(EventVO.LEVEL_INFO);
// _eventDao.persist(lbRuleEvent);
// }
// }
}
@Override
public void deletePrivateTemplateRecord(Long templateId){
if ( templateId != null) {
@ -1885,18 +1816,32 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
}
protected class ExpungeTask implements Runnable {
UserVmManagerImpl _vmMgr;
public ExpungeTask(UserVmManagerImpl vmMgr) {
_vmMgr = vmMgr;
public ExpungeTask() {
}
@Override
public void run() {
GlobalLock scanLock = GlobalLock.getInternLock("UserVMExpunge");
try {
if(scanLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION)) {
if (scanLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION)) {
try {
reallyRun();
List<UserVmVO> vms = _vmDao.findDestroyedVms(new Date(System.currentTimeMillis() - ((long)_expungeDelay << 10)));
if (s_logger.isInfoEnabled()) {
if (vms.size() == 0) {
s_logger.trace("Found " + vms.size() + " vms to expunge.");
} else {
s_logger.info("Found " + vms.size() + " vms to expunge.");
}
}
for (UserVmVO vm : vms) {
try {
expunge(vm, _accountMgr.getSystemUser().getId(), _accountMgr.getSystemAccount());
} catch(Exception e) {
s_logger.warn("Unable to expunge " + vm, e);
}
}
} catch (Exception e) {
s_logger.error("Caught the following Exception", e);
} finally {
scanLock.unlock();
}
@ -1905,15 +1850,6 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
scanLock.releaseRef();
}
}
public void reallyRun() {
try {
s_logger.info("UserVm Expunge Thread is running.");
_vmMgr.expunge();
} catch (Exception e) {
s_logger.error("Caught the following Exception", e);
}
}
}
private static boolean isAdmin(short accountType) {
@ -2610,7 +2546,11 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
User caller = _userDao.findById(userId);
boolean status;
status = _itMgr.destroy(vm, caller, account);
try {
status = _itMgr.destroy(vm, caller, account);
} catch (OperationTimedoutException e) {
throw new CloudRuntimeException("Unable to destroy " + vm, e);
}
if (status) {
UsageEventVO usageEvent = new UsageEventVO(EventTypes.EVENT_VM_DESTROY, vm.getAccountId(), vm.getDataCenterId(), vm.getId(), vm.getName(), vm.getServiceOfferingId(), vm.getTemplateId(), null);
@ -2621,147 +2561,4 @@ public class UserVmManagerImpl implements UserVmManager, UserVmService, Manager
throw new CloudRuntimeException("Failed to destroy vm with id " + vmId);
}
}
// @Override
// public OperationResponse executeRebootVM(RebootVMExecutor executor, VMOperationParam param) {
//
// final UserVmVO vm = _vmDao.findById(param.getVmId());
// String resultDescription;
//
// if (vm == null || vm.getState() == State.Destroyed || vm.getState() == State.Expunging || vm.getRemoved() != null) {
// resultDescription = "VM does not exist or in destroying state";
// executor.getAsyncJobMgr().completeAsyncJob(executor.getJob().getId(),
// AsyncJobResult.STATUS_FAILED, 0, resultDescription);
// if(s_logger.isDebugEnabled())
// s_logger.debug("Execute asynchronize Reboot VM command: " +resultDescription);
// return new OperationResponse(OperationResponse.STATUS_FAILED, resultDescription);
// }
//
// if (vm.getState() == State.Running && vm.getHostId() != null) {
// RebootCommand cmd = new RebootCommand(vm.getInstanceName());
// try {
// long seq = _agentMgr.send(vm.getHostId(), new Commands(cmd), new VMOperationListener(executor, param, vm, 0));
// resultDescription = "Execute asynchronize Reboot VM command: sending command to agent, seq - " + seq;
// if(s_logger.isDebugEnabled())
// s_logger.debug(resultDescription);
// return new OperationResponse(OperationResponse.STATUS_IN_PROGRESS, resultDescription);
// } catch (AgentUnavailableException e) {
// resultDescription = "Agent is not available";
// executor.getAsyncJobMgr().completeAsyncJob(executor.getJob().getId(),
// AsyncJobResult.STATUS_FAILED, 0, resultDescription);
// return new OperationResponse(OperationResponse.STATUS_FAILED, resultDescription);
// }
// }
// resultDescription = "VM is not running or agent host is disconnected";
// executor.getAsyncJobMgr().completeAsyncJob(executor.getJob().getId(),
// AsyncJobResult.STATUS_FAILED, 0, resultDescription);
// return new OperationResponse(OperationResponse.STATUS_FAILED, resultDescription);
// }
// @Override @DB
// public OperationResponse executeDestroyVM(DestroyVMExecutor executor, VMOperationParam param) {
// UserVmVO vm = _vmDao.findById(param.getVmId());
// State state = vm.getState();
// OperationResponse response;
// String resultDescription = "Success";
//
// if (vm == null || state == State.Destroyed || state == State.Expunging || vm.getRemoved() != null) {
// if (s_logger.isDebugEnabled()) {
// s_logger.debug("Unable to find vm or vm is destroyed: " + param.getVmId());
// }
// resultDescription = "VM does not exist or already in destroyed state";
// response = new OperationResponse(OperationResponse.STATUS_FAILED, resultDescription);
// executor.getAsyncJobMgr().completeAsyncJob(executor.getJob().getId(),
// AsyncJobResult.STATUS_FAILED, 0, resultDescription);
// return response;
// }
//
// if(state == State.Stopping) {
// if (s_logger.isDebugEnabled()) {
// s_logger.debug("VM is being stopped: " + param.getVmId());
// }
// resultDescription = "VM is being stopped, please re-try later";
// response = new OperationResponse(OperationResponse.STATUS_FAILED, resultDescription);
// executor.getAsyncJobMgr().completeAsyncJob(executor.getJob().getId(),
// AsyncJobResult.STATUS_FAILED, 0, resultDescription);
// return response;
// }
//
// if (state == State.Running) {
// if (vm.getHostId() == null) {
// resultDescription = "VM host is null (invalid VM)";
// response = new OperationResponse(OperationResponse.STATUS_FAILED, resultDescription);
// executor.getAsyncJobMgr().completeAsyncJob(executor.getJob().getId(),
// AsyncJobResult.STATUS_FAILED, 0, resultDescription);
// if(s_logger.isDebugEnabled())
// s_logger.debug("Execute asynchronize destroy VM command: " + resultDescription);
// return response;
// }
//
// if (!_vmDao.updateIf(vm, Event.StopRequested, vm.getHostId())) {
// resultDescription = "Failed to issue stop command, please re-try later";
// response = new OperationResponse(OperationResponse.STATUS_FAILED, resultDescription);
// executor.getAsyncJobMgr().completeAsyncJob(executor.getJob().getId(),
// AsyncJobResult.STATUS_FAILED, 0, resultDescription);
// if(s_logger.isDebugEnabled())
// s_logger.debug("Execute asynchronize destroy VM command:" + resultDescription);
// return response;
// }
// long childEventId = EventUtils.saveStartedEvent(param.getUserId(), param.getAccountId(),
// EventTypes.EVENT_VM_STOP, "stopping vm " + vm.getName(), 0);
// param.setChildEventId(childEventId);
// StopCommand cmd = new StopCommand(vm, vm.getInstanceName(), vm.getVnet());
// try {
// long seq = _agentMgr.send(vm.getHostId(), new Command[] {cmd}, true,
// new VMOperationListener(executor, param, vm, 0));
// resultDescription = "Execute asynchronize destroy VM command: sending stop command to agent, seq - " + seq;
// if(s_logger.isDebugEnabled())
// s_logger.debug(resultDescription);
// response = new OperationResponse(OperationResponse.STATUS_IN_PROGRESS, resultDescription);
// return response;
// } catch (AgentUnavailableException e) {
// resultDescription = "Agent is not available";
// response = new OperationResponse(OperationResponse.STATUS_FAILED, resultDescription);
// executor.getAsyncJobMgr().completeAsyncJob(executor.getJob().getId(),
// AsyncJobResult.STATUS_FAILED, 0, resultDescription);
// return response;
// }
// }
//
// Transaction txn = Transaction.currentTxn();
// txn.start();
//
// _accountMgr.decrementResourceCount(vm.getAccountId(), ResourceType.user_vm);
// if (!_vmDao.updateIf(vm, VirtualMachine.Event.DestroyRequested, vm.getHostId()) ) {
// resultDescription = "Unable to destroy the vm because it is not in the correct state";
// s_logger.debug(resultDescription + vm.toString());
//
// txn.rollback();
// response = new OperationResponse(OperationResponse.STATUS_FAILED, resultDescription);
// executor.getAsyncJobMgr().completeAsyncJob(executor.getJob().getId(),
// AsyncJobResult.STATUS_FAILED, 0, resultDescription);
// return response;
// }
//
// // Now that the VM is destroyed, clean the network rules associated with it.
// cleanNetworkRules(param.getUserId(), vm.getId());
//
// // Mark the VM's root disk as destroyed
// List<VolumeVO> volumes = _volsDao.findByInstanceAndType(vm.getId(), VolumeType.ROOT);
// for (VolumeVO volume : volumes) {
// _storageMgr.destroyVolume(volume);
// }
//
// // Mark the VM's data disks as detached
// volumes = _volsDao.findByInstanceAndType(vm.getId(), VolumeType.DATADISK);
// for (VolumeVO volume : volumes) {
// _volsDao.detachVolume(volume.getId());
// }
//
// txn.commit();
// response = new OperationResponse(OperationResponse.STATUS_SUCCEEDED, resultDescription);
// executor.getAsyncJobMgr().completeAsyncJob(executor.getJob().getId(),
// AsyncJobResult.STATUS_SUCCEEDED, 0, "success");
// return response;
// }
}

View File

@ -145,6 +145,4 @@ public interface VirtualMachineGuru<T extends VirtualMachine> {
boolean migrate(T vm, HostVO host) throws AgentUnavailableException, OperationTimedoutException;
boolean completeMigration(T vm, HostVO host) throws AgentUnavailableException, OperationTimedoutException;
boolean destroy(T vm) throws AgentUnavailableException;
}

View File

@ -21,6 +21,7 @@ import java.util.List;
import java.util.Map;
import com.cloud.deploy.DeploymentPlan;
import com.cloud.exception.AgentUnavailableException;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.OperationTimedoutException;
@ -74,7 +75,7 @@ public interface VirtualMachineManager extends Manager {
<T extends VMInstanceVO> boolean stop(T vm, User caller, Account account) throws ResourceUnavailableException;
<T extends VMInstanceVO> boolean destroy(T vm, User caller, Account account) throws ResourceUnavailableException;
<T extends VMInstanceVO> boolean expunge(T vm, User caller, Account account) throws ResourceUnavailableException;
<T extends VMInstanceVO> void registerGuru(VirtualMachine.Type type, VirtualMachineGuru<T> guru);
@ -84,5 +85,9 @@ public interface VirtualMachineManager extends Manager {
<T extends VMInstanceVO> boolean advanceStop(T vm, User caller, Account account) throws ResourceUnavailableException, OperationTimedoutException, ConcurrentOperationException;
<T extends VMInstanceVO> boolean advanceDestroy(T vm, User caller, Account account) throws ResourceUnavailableException, OperationTimedoutException, ConcurrentOperationException;
<T extends VMInstanceVO> boolean advanceExpunge(T vm, User caller, Account account) throws ResourceUnavailableException, OperationTimedoutException, ConcurrentOperationException;
<T extends VMInstanceVO> boolean remove(T vm, User caller, Account account);
<T extends VMInstanceVO> boolean destroy(T vm, User caller, Account account) throws AgentUnavailableException, OperationTimedoutException, ConcurrentOperationException;
}

View File

@ -36,7 +36,6 @@ import com.cloud.agent.api.StopAnswer;
import com.cloud.agent.api.StopCommand;
import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.agent.manager.Commands;
import com.cloud.capacity.dao.CapacityDao;
import com.cloud.cluster.ClusterManager;
import com.cloud.cluster.ClusterManagerListener;
import com.cloud.cluster.ManagementServerHostVO;
@ -60,17 +59,16 @@ import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.InsufficientServerCapacityException;
import com.cloud.exception.OperationTimedoutException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.hypervisor.HypervisorGuru;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.hypervisor.HypervisorGuru;
import com.cloud.network.NetworkManager;
import com.cloud.network.NetworkVO;
import com.cloud.service.ServiceOfferingVO;
import com.cloud.service.dao.ServiceOfferingDao;
import com.cloud.stateListener.VMStateListener;
import com.cloud.storage.DiskOfferingVO;
import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.StorageManager;
import com.cloud.storage.VMTemplateVO;
import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.Volume.VolumeType;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.user.Account;
@ -113,7 +111,6 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Cluster
@Inject private DomainDao _domainDao;
@Inject private ClusterManager _clusterMgr;
@Inject private ItWorkDao _workDao;
@Inject private CapacityDao _capacityDao;
@Inject private UserVmDao _userVmDao;
@Inject private DomainRouterDao _routerDao;
@Inject private ConsoleProxyDao _consoleDao;
@ -238,9 +235,9 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Cluster
}
@Override
public <T extends VMInstanceVO> boolean destroy(T vm, User caller, Account account) throws ResourceUnavailableException {
public <T extends VMInstanceVO> boolean expunge(T vm, User caller, Account account) throws ResourceUnavailableException {
try {
return advanceDestroy(vm, caller, account);
return advanceExpunge(vm, caller, account);
} catch (OperationTimedoutException e) {
throw new CloudRuntimeException("Operation timed out", e);
} catch (ConcurrentOperationException e) {
@ -249,14 +246,19 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Cluster
}
@Override
public <T extends VMInstanceVO> boolean advanceDestroy(T vm, User caller, Account account) throws ResourceUnavailableException, OperationTimedoutException, ConcurrentOperationException {
if (vm == null || vm.getState() == State.Destroyed || vm.getState() == State.Expunging || vm.getRemoved() != null) {
public <T extends VMInstanceVO> boolean advanceExpunge(T vm, User caller, Account account) throws ResourceUnavailableException, OperationTimedoutException, ConcurrentOperationException {
if (vm == null || vm.getRemoved() != null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Unable to find vm or vm is destroyed: " + vm);
}
return true;
}
if (!stateTransitTo(vm, VirtualMachine.Event.ExpungeOperation, vm.getHostId())) {
s_logger.debug("Unable to destroy the vm because it is not in the correct state: " + vm.toString());
return false;
}
if (s_logger.isDebugEnabled()) {
s_logger.debug("Destroying vm " + vm);
}
@ -271,9 +273,12 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Cluster
EventUtils.saveEvent(userId, vm.getAccountId(), EventVO.LEVEL_INFO, EventTypes.EVENT_VM_STOP, "Successfully stopped VM instance : " + vm.getId(), startEventId);
}
VirtualMachineProfile<T> profile = new VirtualMachineProfileImpl<T>(vm);
_networkMgr.cleanupNics(profile);
//Clean up volumes based on the vm's instance id
_storageMgr.cleanupVolumes(vm.getId());
VirtualMachineGuru<T> guru = getVmGuru(vm);
vm = guru.findById(vm.getId());
@ -591,6 +596,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Cluster
_stateMachine.addTransition(State.Stopped, VirtualMachine.Event.StopRequested, State.Stopped);
_stateMachine.addTransition(State.Stopped, VirtualMachine.Event.AgentReportStopped, State.Stopped);
_stateMachine.addTransition(State.Stopped, VirtualMachine.Event.OperationFailed, State.Error);
_stateMachine.addTransition(State.Stopped, VirtualMachine.Event.ExpungeOperation, State.Expunging);
_stateMachine.addTransition(State.Starting, VirtualMachine.Event.OperationRetry, State.Starting);
_stateMachine.addTransition(State.Starting, VirtualMachine.Event.OperationSucceeded, State.Running);
_stateMachine.addTransition(State.Starting, VirtualMachine.Event.OperationFailed, State.Stopped);
@ -635,4 +641,34 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Cluster
return _stateMachine.transitTO(vm, e, id, _vmDao);
}
}
@Override
public <T extends VMInstanceVO> boolean remove(T vm, User user, Account caller) {
return _vmDao.remove(vm.getId());
}
@Override
public <T extends VMInstanceVO> boolean destroy(T vm, User user, Account caller) throws AgentUnavailableException, OperationTimedoutException, ConcurrentOperationException {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Destroying vm " + vm.toString());
}
if (vm == null || vm.getState() == State.Destroyed || vm.getState() == State.Expunging || vm.getRemoved() != null) {
if (s_logger.isDebugEnabled()) {
s_logger.debug("Unable to find vm or vm is destroyed: " + vm);
}
return true;
}
if (!advanceStop(vm, user, caller)) {
s_logger.debug("Unable to stop " + vm);
return false;
}
if (!stateTransitTo(vm, VirtualMachine.Event.DestroyRequested, vm.getHostId())) {
s_logger.debug("Unable to destroy the vm because it is not in the correct state: " + vm.toString());
return false;
}
return true;
}
}