Update template and storage manager to allow hypervisor based command delegation

This commit is contained in:
Kelven Yang 2011-02-18 11:37:26 -08:00
parent 7aa18d4fe2
commit 8695e7250c
9 changed files with 169 additions and 18 deletions

View File

@ -17,6 +17,7 @@
*/
package com.cloud.hypervisor;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.utils.component.Adapter;
@ -33,4 +34,13 @@ public interface HypervisorGuru extends Adapter {
* @return
*/
<T extends VirtualMachine> VirtualMachineTO implement(VirtualMachineProfile<T> vm);
/**
* Give hypervisor guru opportunity to decide if certain command needs to be delegated to other host, mainly to secondary storage VM host
* @param hostId original hypervisor host
* @param cmd command that is going to be sent, hypervisor guru usually needs to register various context objects into the command object
*
* @return delegated host id if the command will be delegated
*/
long getCommandHostDelegation(long hostId, Command cmd);
}

View File

@ -62,6 +62,7 @@ import com.cloud.ha.HighAvailabilityManagerImpl;
import com.cloud.ha.dao.HighAvailabilityDaoImpl;
import com.cloud.host.dao.DetailsDaoImpl;
import com.cloud.host.dao.HostDaoImpl;
import com.cloud.hypervisor.HypervisorGuruManagerImpl;
import com.cloud.maid.StackMaidManagerImpl;
import com.cloud.maid.dao.StackMaidDaoImpl;
import com.cloud.maint.UpgradeManagerImpl;
@ -79,7 +80,6 @@ import com.cloud.network.lb.LoadBalancingRulesManagerImpl;
import com.cloud.network.ovs.OvsNetworkManagerImpl;
import com.cloud.network.ovs.OvsTunnelManagerImpl;
import com.cloud.network.ovs.dao.GreTunnelDaoImpl;
import com.cloud.network.ovs.dao.OvsTunnelAccountDao;
import com.cloud.network.ovs.dao.OvsTunnelAccountDaoImpl;
import com.cloud.network.ovs.dao.OvsTunnelDaoImpl;
import com.cloud.network.ovs.dao.OvsWorkDaoImpl;
@ -322,6 +322,8 @@ public class DefaultComponentLibrary implements ComponentLibrary {
addManager("Cluster Manager", ClusterManagerImpl.class);
addManager("ClusteredAgentManager", ClusteredAgentManagerImpl.class);
addManager("VirtualMachineManager", ClusteredVirtualMachineManagerImpl.class);
addManager("HypervisorGuruManager", HypervisorGuruManagerImpl.class);
ComponentInfo<? extends Manager> info = addManager("ConsoleProxyManager", ConsoleProxyManagerImpl.class);
info.addParameter("consoleproxy.sslEnabled", "true");
}

View File

@ -19,6 +19,7 @@ package com.cloud.hypervisor;
import java.util.List;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.to.NicTO;
import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.agent.api.to.VolumeTO;
@ -79,4 +80,7 @@ public abstract class HypervisorGuruBase extends AdapterBase implements Hypervis
return to;
}
public long getCommandHostDelegation(long hostId, Command cmd) {
return hostId;
}
}

View File

@ -0,0 +1,11 @@
package com.cloud.hypervisor;
import com.cloud.agent.api.Command;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.utils.component.Manager;
public interface HypervisorGuruManager extends Manager {
HypervisorGuru getGuru(HypervisorType hypervisorType);
long getGuruProcessedCommandTargetHost(long hostId, Command cmd);
}

View File

@ -0,0 +1,73 @@
package com.cloud.hypervisor;
import java.util.HashMap;
import java.util.Map;
import javax.ejb.Local;
import javax.naming.ConfigurationException;
import org.apache.log4j.Logger;
import com.cloud.agent.api.Command;
import com.cloud.host.Host;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.utils.component.Adapters;
import com.cloud.utils.component.ComponentLocator;
import com.cloud.utils.component.Inject;
@Local(value = { HypervisorGuruManager.class } )
public class HypervisorGuruManagerImpl implements HypervisorGuruManager {
public static final Logger s_logger = Logger.getLogger(HypervisorGuruManagerImpl.class.getName());
@Inject HostDao _hostDao;
String _name;
Map<HypervisorType, HypervisorGuru> _hvGurus = new HashMap<HypervisorType, HypervisorGuru>();
@Override
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
_name = name;
ComponentLocator locator = ComponentLocator.getCurrentLocator();
Adapters<HypervisorGuru> hvGurus = locator.getAdapters(HypervisorGuru.class);
for (HypervisorGuru guru : hvGurus) {
_hvGurus.put(guru.getHypervisorType(), guru);
}
return true;
}
@Override
public boolean start() {
return true;
}
@Override
public boolean stop() {
return true;
}
@Override
public String getName() {
return _name;
}
public HypervisorGuru getGuru(HypervisorType hypervisorType) {
return _hvGurus.get(hypervisorType);
}
public long getGuruProcessedCommandTargetHost(long hostId, Command cmd) {
HostVO hostVo = _hostDao.findById(hostId);
HypervisorGuru hvGuru = null;
if(hostVo.getType() == Host.Type.Routing) {
hvGuru = _hvGurus.get(hostVo.getHypervisorType());
}
if(hvGuru != null)
return hvGuru.getCommandHostDelegation(hostId, cmd);
return hostId;
}
}

View File

@ -19,7 +19,18 @@ package com.cloud.hypervisor;
import javax.ejb.Local;
import com.cloud.agent.api.BackupSnapshotCommand;
import com.cloud.agent.api.Command;
import com.cloud.agent.api.CreatePrivateTemplateFromSnapshotCommand;
import com.cloud.agent.api.CreatePrivateTemplateFromVolumeCommand;
import com.cloud.agent.api.CreateVolumeFromSnapshotCommand;
import com.cloud.agent.api.DeleteSnapshotBackupCommand;
import com.cloud.agent.api.DeleteSnapshotsDirCommand;
import com.cloud.agent.api.storage.CopyVolumeCommand;
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
import com.cloud.agent.api.to.VirtualMachineTO;
import com.cloud.host.dao.DetailsDao;
import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.storage.GuestOSVO;
import com.cloud.storage.dao.GuestOSDao;
@ -31,6 +42,8 @@ import com.cloud.vm.VirtualMachineProfile;
@Local(value=HypervisorGuru.class)
public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru {
@Inject GuestOSDao _guestOsDao;
@Inject HostDao _hostDao;
@Inject DetailsDao _hostDetailsDao;
protected VMwareGuru() {
super();
@ -51,4 +64,43 @@ public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru {
to.setOs(guestOS.getDisplayName());
return to;
}
@Override
public long getCommandHostDelegation(long hostId, Command cmd) {
boolean needDelegation = false;
if(cmd instanceof PrimaryStorageDownloadCommand ||
cmd instanceof BackupSnapshotCommand ||
cmd instanceof DeleteSnapshotsDirCommand ||
cmd instanceof DeleteSnapshotBackupCommand ||
cmd instanceof CreatePrivateTemplateFromVolumeCommand ||
cmd instanceof CreatePrivateTemplateFromSnapshotCommand ||
cmd instanceof CopyVolumeCommand ||
cmd instanceof CreateVolumeFromSnapshotCommand) {
needDelegation = true;
}
// Enable when SSVM packaging is ready
/*
if(needDelegation) {
HostVO host = _hostDao.findById(hostId);
assert(host != null);
assert(host.getHypervisorType() == HypervisorType.VMware);
long dcId = host.getDataCenterId();
HostVO hostSecStorage = _hostDao.findSecondaryStorageHost(dcId);
if(hostSecStorage != null && hostSecStorage.getStatus() == Status.Up) {
// TODO, we need to make sure agent is actually connected too
cmd.setContextParam("hypervisor", HypervisorType.VMware.toString());
Map<String, String> hostDetails = _hostDetailsDao.findDetails(hostId);
cmd.setContextParam("guid", hostDetails.get("guid"));
cmd.setContextParam("username", hostDetails.get("username"));
cmd.setContextParam("password", hostDetails.get("password"));
return hostSecStorage.getId();
}
}
*/
return hostId;
}
}

View File

@ -114,6 +114,7 @@ import com.cloud.host.Status;
import com.cloud.host.dao.DetailsDao;
import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.hypervisor.HypervisorGuruManager;
import com.cloud.network.NetworkManager;
import com.cloud.network.router.VirtualNetworkApplianceManager;
import com.cloud.offering.ServiceOffering;
@ -231,7 +232,7 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
@Inject protected DomainRouterDao _domrDao;
@Inject protected SecondaryStorageVmDao _secStrgDao;
@Inject protected StoragePoolWorkDao _storagePoolWorkDao;
@Inject protected HypervisorGuruManager _hvGuruMgr;
@Inject(adapter=StoragePoolAllocator.class)
protected Adapters<StoragePoolAllocator> _storagePoolAllocators;
@ -1636,10 +1637,12 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag
List<Answer> answers = new ArrayList<Answer>();
Command[] cmdArray = cmds.toCommands();
for (Command cmd : cmdArray) {
long targetHostId = _hvGuruMgr.getGuruProcessedCommandTargetHost(hostId, cmd);
if (cmd instanceof BackupSnapshotCommand) {
answers.add(_agentMgr.send(hostId, cmd, _snapshotTimeout));
answers.add(_agentMgr.send(targetHostId, cmd, _snapshotTimeout));
} else {
answers.add(_agentMgr.send(hostId, cmd));
answers.add(_agentMgr.send(targetHostId, cmd));
}
}
return new Pair<Long, Answer[]>(hostId, answers.toArray(new Answer[answers.size()]));

View File

@ -36,7 +36,6 @@ import com.cloud.agent.api.Answer;
import com.cloud.agent.api.storage.DestroyCommand;
import com.cloud.agent.api.storage.PrimaryStorageDownloadAnswer;
import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand;
import com.cloud.api.ApiDBUtils;
import com.cloud.api.BaseCmd;
import com.cloud.api.ServerApiException;
import com.cloud.api.commands.AttachIsoCmd;
@ -58,8 +57,6 @@ import com.cloud.dc.DataCenterVO;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.domain.dao.DomainDao;
import com.cloud.event.EventTypes;
import com.cloud.event.EventUtils;
import com.cloud.event.EventVO;
import com.cloud.event.UsageEventVO;
import com.cloud.event.dao.EventDao;
import com.cloud.event.dao.UsageEventDao;
@ -71,6 +68,7 @@ import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.Hypervisor;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.hypervisor.HypervisorGuruManager;
import com.cloud.storage.SnapshotVO;
import com.cloud.storage.Storage;
import com.cloud.storage.Storage.ImageFormat;
@ -161,6 +159,7 @@ public class TemplateManagerImpl implements TemplateManager, Manager, TemplateSe
@Inject UserVmManager _vmMgr;
@Inject ConfigurationDao _configDao;
@Inject UsageEventDao _usageEventDao;
@Inject HypervisorGuruManager _hvGuruMgr;
protected SearchBuilder<VMTemplateHostVO> HostTemplateStatesSearch;
@Override
@ -679,7 +678,9 @@ public class TemplateManagerImpl implements TemplateManager, Manager, TemplateSe
}
dcmd.setLocalPath(vo.getLocalPath());
// set 120 min timeout for this command
PrimaryStorageDownloadAnswer answer = (PrimaryStorageDownloadAnswer)_agentMgr.easySend(vo.getHostId(), dcmd, 120*60*1000);
PrimaryStorageDownloadAnswer answer = (PrimaryStorageDownloadAnswer)_agentMgr.easySend(
_hvGuruMgr.getGuruProcessedCommandTargetHost(vo.getHostId(), dcmd), dcmd, 120*60*1000);
if (answer != null && answer.getResult() ) {
templateStoragePoolRef.setDownloadPercent(100);
templateStoragePoolRef.setDownloadState(Status.DOWNLOADED);

View File

@ -92,6 +92,7 @@ import com.cloud.host.Status;
import com.cloud.host.dao.HostDao;
import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.hypervisor.HypervisorGuru;
import com.cloud.hypervisor.HypervisorGuruManager;
import com.cloud.maid.StackMaid;
import com.cloud.network.NetworkManager;
import com.cloud.network.NetworkVO;
@ -170,12 +171,12 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene
@Inject protected HighAvailabilityManager _haMgr;
@Inject protected HostPodDao _podDao;
@Inject protected DataCenterDao _dcDao;
@Inject protected HypervisorGuruManager _hvGuruMgr;
@Inject(adapter=DeploymentPlanner.class)
protected Adapters<DeploymentPlanner> _planners;
Map<VirtualMachine.Type, VirtualMachineGuru<? extends VMInstanceVO>> _vmGurus = new HashMap<VirtualMachine.Type, VirtualMachineGuru<? extends VMInstanceVO>>();
Map<HypervisorType, HypervisorGuru> _hvGurus = new HashMap<HypervisorType, HypervisorGuru>();
protected StateMachine2<State, VirtualMachine.Event, VirtualMachine> _stateMachine;
ScheduledExecutorService _executor = null;
@ -375,12 +376,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene
ReservationContextImpl.setComponents(_userDao, _domainDao, _accountDao);
VirtualMachineProfileImpl.setComponents(_offeringDao, _templateDao, _accountDao);
Adapters<HypervisorGuru> hvGurus = locator.getAdapters(HypervisorGuru.class);
for (HypervisorGuru guru : hvGurus) {
_hvGurus.put(guru.getHypervisorType(), guru);
}
_cancelWait = NumbersUtil.parseLong(params.get(Config.VmOpCancelInterval.key()), 3600);
_cleanupWait = NumbersUtil.parseLong(params.get(Config.VmOpCleanupWait.key()), 3600);
_cleanupInterval = NumbersUtil.parseLong(params.get(Config.VmOpCleanupInterval.key()), 86400) * 1000;
@ -538,8 +534,7 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene
ServiceOfferingVO offering = _offeringDao.findById(vm.getServiceOfferingId());
VMTemplateVO template = _templateDao.findById(vm.getTemplateId());
DataCenterDeployment plan = new DataCenterDeployment(vm.getDataCenterId(), vm.getPodId(), null, null);
HypervisorGuru hvGuru = _hvGurus.get(vm.getHypervisorType());
HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType());
try {
Journal journal = start.second().getJournal();
@ -934,8 +929,8 @@ public class VirtualMachineManagerImpl implements VirtualMachineManager, Listene
VirtualMachineProfile<VMInstanceVO> profile = new VirtualMachineProfileImpl<VMInstanceVO>(vm);
_networkMgr.prepareNicForMigration(profile, dest);
_storageMgr.prepareForMigration(profile, dest);
HypervisorGuru hvGuru = _hvGuruMgr.getGuru(vm.getHypervisorType());
HypervisorGuru hvGuru = _hvGurus.get(vm.getHypervisorType());
VirtualMachineTO to = hvGuru.implement(profile);
PrepareForMigrationCommand pfmc = new PrepareForMigrationCommand(to);