diff --git a/api/src/com/cloud/hypervisor/HypervisorGuru.java b/api/src/com/cloud/hypervisor/HypervisorGuru.java index 9f4fc7a1053..f5a6a40968b 100644 --- a/api/src/com/cloud/hypervisor/HypervisorGuru.java +++ b/api/src/com/cloud/hypervisor/HypervisorGuru.java @@ -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 */ VirtualMachineTO implement(VirtualMachineProfile 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); } diff --git a/server/src/com/cloud/configuration/DefaultComponentLibrary.java b/server/src/com/cloud/configuration/DefaultComponentLibrary.java index 18a5c03501f..a94fa8182f9 100644 --- a/server/src/com/cloud/configuration/DefaultComponentLibrary.java +++ b/server/src/com/cloud/configuration/DefaultComponentLibrary.java @@ -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 info = addManager("ConsoleProxyManager", ConsoleProxyManagerImpl.class); info.addParameter("consoleproxy.sslEnabled", "true"); } diff --git a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java index 2b7e858e60b..84944322ee1 100644 --- a/server/src/com/cloud/hypervisor/HypervisorGuruBase.java +++ b/server/src/com/cloud/hypervisor/HypervisorGuruBase.java @@ -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; + } } diff --git a/server/src/com/cloud/hypervisor/HypervisorGuruManager.java b/server/src/com/cloud/hypervisor/HypervisorGuruManager.java new file mode 100644 index 00000000000..43e1937ee10 --- /dev/null +++ b/server/src/com/cloud/hypervisor/HypervisorGuruManager.java @@ -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); +} + diff --git a/server/src/com/cloud/hypervisor/HypervisorGuruManagerImpl.java b/server/src/com/cloud/hypervisor/HypervisorGuruManagerImpl.java new file mode 100644 index 00000000000..37c8561f7bf --- /dev/null +++ b/server/src/com/cloud/hypervisor/HypervisorGuruManagerImpl.java @@ -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 _hvGurus = new HashMap(); + + @Override + public boolean configure(String name, Map params) throws ConfigurationException { + _name = name; + ComponentLocator locator = ComponentLocator.getCurrentLocator(); + + Adapters 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; + } +} diff --git a/server/src/com/cloud/hypervisor/VMwareGuru.java b/server/src/com/cloud/hypervisor/VMwareGuru.java index fa210711daf..cc1a74eafab 100644 --- a/server/src/com/cloud/hypervisor/VMwareGuru.java +++ b/server/src/com/cloud/hypervisor/VMwareGuru.java @@ -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 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; + } } diff --git a/server/src/com/cloud/storage/StorageManagerImpl.java b/server/src/com/cloud/storage/StorageManagerImpl.java index cbd2264f0c3..e6d9ef2eb97 100755 --- a/server/src/com/cloud/storage/StorageManagerImpl.java +++ b/server/src/com/cloud/storage/StorageManagerImpl.java @@ -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 _storagePoolAllocators; @@ -1636,10 +1637,12 @@ public class StorageManagerImpl implements StorageManager, StorageService, Manag List answers = new ArrayList(); 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(hostId, answers.toArray(new Answer[answers.size()])); diff --git a/server/src/com/cloud/template/TemplateManagerImpl.java b/server/src/com/cloud/template/TemplateManagerImpl.java index 9097f3d8630..7d32a6e2400 100755 --- a/server/src/com/cloud/template/TemplateManagerImpl.java +++ b/server/src/com/cloud/template/TemplateManagerImpl.java @@ -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 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); diff --git a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java index 808e555cfef..06f3274d8d7 100755 --- a/server/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/server/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -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 _planners; Map> _vmGurus = new HashMap>(); - Map _hvGurus = new HashMap(); protected StateMachine2 _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 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 profile = new VirtualMachineProfileImpl(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);