| // Copyright 2012 Citrix Systems, Inc. Licensed under the |
| // Apache License, Version 2.0 (the "License"); you may not use this |
| // file except in compliance with the License. Citrix Systems, Inc. |
| // reserves all rights not expressly granted by the License. |
| // You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // |
| // Automatically generated by addcopyright.py at 04/03/2012 |
| package com.cloud.hypervisor.guru;
|
|
|
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.Comparator; |
| import java.util.HashMap; |
| import java.util.List; |
| import java.util.Map; |
| |
| import javax.ejb.Local; |
| |
| import org.apache.log4j.Logger; |
| |
| 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.storage.CopyVolumeCommand; |
| import com.cloud.agent.api.storage.PrimaryStorageDownloadCommand; |
| import com.cloud.agent.api.to.NicTO; |
| import com.cloud.agent.api.to.VirtualMachineTO; |
| import com.cloud.cluster.CheckPointManager; |
| import com.cloud.cluster.ClusterManager; |
| import com.cloud.exception.InsufficientAddressCapacityException; |
| import com.cloud.host.HostVO; |
| import com.cloud.host.dao.HostDao; |
| import com.cloud.host.dao.HostDetailsDao; |
| import com.cloud.hypervisor.Hypervisor.HypervisorType; |
| import com.cloud.hypervisor.HypervisorGuru; |
| import com.cloud.hypervisor.HypervisorGuruBase; |
| import com.cloud.hypervisor.vmware.VmwareCleanupMaid; |
| import com.cloud.hypervisor.vmware.manager.VmwareManager; |
| import com.cloud.hypervisor.vmware.mo.VirtualEthernetCardType; |
| import com.cloud.network.NetworkManager; |
| import com.cloud.network.NetworkVO; |
| import com.cloud.network.Networks.TrafficType; |
| import com.cloud.network.dao.NetworkDao; |
| import com.cloud.secstorage.CommandExecLogDao; |
| import com.cloud.secstorage.CommandExecLogVO; |
| import com.cloud.storage.GuestOSVO; |
| import com.cloud.storage.dao.GuestOSDao; |
| import com.cloud.storage.secondary.SecondaryStorageVmManager; |
| import com.cloud.template.VirtualMachineTemplate.BootloaderType; |
| import com.cloud.utils.Pair; |
| import com.cloud.utils.component.Inject; |
| import com.cloud.utils.db.DB; |
| import com.cloud.utils.exception.CloudRuntimeException; |
| import com.cloud.utils.net.NetUtils; |
| import com.cloud.vm.ConsoleProxyVO; |
| import com.cloud.vm.DomainRouterVO; |
| import com.cloud.vm.NicProfile; |
| import com.cloud.vm.SecondaryStorageVmVO; |
| import com.cloud.vm.VirtualMachine; |
| import com.cloud.vm.VirtualMachineProfile; |
| import com.cloud.vm.VmDetailConstants; |
|
|
| @Local(value=HypervisorGuru.class)
|
| public class VMwareGuru extends HypervisorGuruBase implements HypervisorGuru {
|
| private static final Logger s_logger = Logger.getLogger(VMwareGuru.class);
|
|
|
| @Inject NetworkDao _networkDao; |
| @Inject GuestOSDao _guestOsDao;
|
| @Inject HostDao _hostDao;
|
| @Inject HostDetailsDao _hostDetailsDao;
|
| @Inject CommandExecLogDao _cmdExecLogDao;
|
| @Inject ClusterManager _clusterMgr;
|
| @Inject VmwareManager _vmwareMgr;
|
| @Inject SecondaryStorageVmManager _secStorageMgr; |
| @Inject CheckPointManager _checkPointMgr; |
| @Inject NetworkManager _networkMgr;
|
|
|
| protected VMwareGuru() {
|
| super();
|
| }
|
|
|
| @Override
|
| public HypervisorType getHypervisorType() {
|
| return HypervisorType.VMware;
|
| }
|
|
|
| @Override
|
| public <T extends VirtualMachine> VirtualMachineTO implement(VirtualMachineProfile<T> vm) { |
| VirtualMachineTO to = toVirtualMachineTO(vm);
|
| to.setBootloader(BootloaderType.HVM); |
| |
| Map<String, String> details = to.getDetails(); |
| if(details == null) |
| details = new HashMap<String, String>(); |
| |
| String nicDeviceType = details.get(VmDetailConstants.NIC_ADAPTER); |
| if(vm.getVirtualMachine() instanceof DomainRouterVO || vm.getVirtualMachine() instanceof ConsoleProxyVO |
| || vm.getVirtualMachine() instanceof SecondaryStorageVmVO) { |
| |
| if(nicDeviceType == null) { |
| details.put(VmDetailConstants.NIC_ADAPTER, _vmwareMgr.getSystemVMDefaultNicAdapterType()); |
| } else { |
| try { |
| VirtualEthernetCardType.valueOf(nicDeviceType); |
| } catch (Exception e) { |
| s_logger.warn("Invalid NIC device type " + nicDeviceType + " is specified in VM details, switch to default E1000"); |
| details.put(VmDetailConstants.NIC_ADAPTER, VirtualEthernetCardType.E1000.toString()); |
| } |
| } |
| } else { |
| // for user-VM, use E1000 as default |
| if(nicDeviceType == null) { |
| details.put(VmDetailConstants.NIC_ADAPTER, VirtualEthernetCardType.E1000.toString()); |
| } else { |
| try { |
| VirtualEthernetCardType.valueOf(nicDeviceType); |
| } catch (Exception e) { |
| s_logger.warn("Invalid NIC device type " + nicDeviceType + " is specified in VM details, switch to default E1000"); |
| details.put(VmDetailConstants.NIC_ADAPTER, VirtualEthernetCardType.E1000.toString()); |
| } |
| } |
| }
|
| to.setDetails(details); |
| |
| if(vm.getVirtualMachine() instanceof DomainRouterVO) { |
| List<NicProfile> nicProfiles = vm.getNics(); |
| NicProfile publicNicProfile = null; |
| |
| for(NicProfile nicProfile : nicProfiles) { |
| if(nicProfile.getTrafficType() == TrafficType.Public) { |
| publicNicProfile = nicProfile; |
| break; |
| } |
| } |
| |
| if(publicNicProfile != null) { |
| NicTO[] nics = to.getNics(); |
| |
| // reserve extra NICs |
| NicTO[] expandedNics = new NicTO[nics.length + _vmwareMgr.getRouterExtraPublicNics()]; |
| int i = 0; |
| int deviceId = -1; |
| for(i = 0; i < nics.length; i++) { |
| expandedNics[i] = nics[i]; |
| if(nics[i].getDeviceId() > deviceId) |
| deviceId = nics[i].getDeviceId(); |
| } |
| deviceId++; |
| |
| long networkId = publicNicProfile.getNetworkId(); |
| NetworkVO network = _networkDao.findById(networkId); |
| |
| for(; i < nics.length + _vmwareMgr.getRouterExtraPublicNics(); i++) { |
| NicTO nicTo = new NicTO(); |
| |
| nicTo.setDeviceId(deviceId++); |
| nicTo.setBroadcastType(publicNicProfile.getBroadcastType()); |
| nicTo.setType(publicNicProfile.getTrafficType()); |
| nicTo.setIp("0.0.0.0"); |
| nicTo.setNetmask("255.255.255.255"); |
| |
| try { |
| String mac = _networkMgr.getNextAvailableMacAddressInNetwork(networkId); |
| nicTo.setMac(mac); |
| } catch (InsufficientAddressCapacityException e) { |
| throw new CloudRuntimeException("unable to allocate mac address on network: " + networkId); |
| } |
| nicTo.setDns1(publicNicProfile.getDns1()); |
| nicTo.setDns2(publicNicProfile.getDns2()); |
| if (publicNicProfile.getGateway() != null) { |
| nicTo.setGateway(publicNicProfile.getGateway()); |
| } else { |
| nicTo.setGateway(network.getGateway()); |
| } |
| nicTo.setDefaultNic(false); |
| nicTo.setBroadcastUri(publicNicProfile.getBroadCastUri()); |
| nicTo.setIsolationuri(publicNicProfile.getIsolationUri()); |
| |
| Integer networkRate = _networkMgr.getNetworkRate(network.getId(), null); |
| nicTo.setNetworkRateMbps(networkRate); |
| |
| expandedNics[i] = nicTo; |
| } |
| |
| to.setNics(expandedNics); |
| } |
| |
| StringBuffer sbMacSequence = new StringBuffer(); |
| for(NicTO nicTo : sortNicsByDeviceId(to.getNics())) { |
| sbMacSequence.append(nicTo.getMac()).append("|"); |
| } |
| sbMacSequence.deleteCharAt(sbMacSequence.length() - 1); |
| String bootArgs = to.getBootArgs(); |
| to.setBootArgs(bootArgs + " nic_macs=" + sbMacSequence.toString()); |
| } |
|
|
| // Determine the VM's OS description
|
| GuestOSVO guestOS = _guestOsDao.findById(vm.getVirtualMachine().getGuestOSId());
|
| to.setOs(guestOS.getDisplayName());
|
| return to;
|
| }
|
| |
| private NicTO[] sortNicsByDeviceId(NicTO[] nics) { |
| |
| List<NicTO> listForSort = new ArrayList<NicTO>(); |
| for (NicTO nic : nics) { |
| listForSort.add(nic); |
| } |
| Collections.sort(listForSort, new Comparator<NicTO>() { |
| |
| @Override |
| public int compare(NicTO arg0, NicTO arg1) { |
| if (arg0.getDeviceId() < arg1.getDeviceId()) { |
| return -1; |
| } else if (arg0.getDeviceId() == arg1.getDeviceId()) { |
| return 0; |
| } |
| |
| return 1; |
| } |
| }); |
| |
| return listForSort.toArray(new NicTO[0]); |
| } |
|
|
| @Override @DB
|
| public long getCommandHostDelegation(long hostId, Command cmd) {
|
| boolean needDelegation = false;
|
|
|
| if(cmd instanceof PrimaryStorageDownloadCommand ||
|
| cmd instanceof BackupSnapshotCommand ||
|
| cmd instanceof CreatePrivateTemplateFromVolumeCommand ||
|
| cmd instanceof CreatePrivateTemplateFromSnapshotCommand ||
|
| cmd instanceof CopyVolumeCommand ||
|
| cmd instanceof CreateVolumeFromSnapshotCommand) {
|
| needDelegation = true;
|
| }
|
|
|
| if(needDelegation) {
|
| HostVO host = _hostDao.findById(hostId);
|
| assert(host != null);
|
| assert(host.getHypervisorType() == HypervisorType.VMware);
|
| long dcId = host.getDataCenterId();
|
|
|
| Pair<HostVO, SecondaryStorageVmVO> cmdTarget = _secStorageMgr.assignSecStorageVm(dcId, cmd);
|
| if(cmdTarget != null) {
|
| // 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", resolveNameInGuid(hostDetails.get("guid")));
|
| cmd.setContextParam("username", hostDetails.get("username"));
|
| cmd.setContextParam("password", hostDetails.get("password"));
|
| cmd.setContextParam("serviceconsole", _vmwareMgr.getServiceConsolePortGroupName());
|
| cmd.setContextParam("manageportgroup", _vmwareMgr.getManagementPortGroupName()); |
|
|
| CommandExecLogVO execLog = new CommandExecLogVO(cmdTarget.first().getId(), cmdTarget.second().getId(), cmd.getClass().getSimpleName(), 1);
|
| _cmdExecLogDao.persist(execLog);
|
| cmd.setContextParam("execid", String.valueOf(execLog.getId())); |
| |
| if(cmd instanceof BackupSnapshotCommand || |
| cmd instanceof CreatePrivateTemplateFromVolumeCommand || |
| cmd instanceof CreatePrivateTemplateFromSnapshotCommand || |
| cmd instanceof CopyVolumeCommand || |
| cmd instanceof CreateVolumeFromSnapshotCommand) { |
| |
| String workerName = _vmwareMgr.composeWorkerName(); |
| long checkPointId = _checkPointMgr.pushCheckPoint(new VmwareCleanupMaid(hostDetails.get("guid"), workerName)); |
| cmd.setContextParam("worker", workerName); |
| cmd.setContextParam("checkpoint", String.valueOf(checkPointId)); |
| |
| // some commands use 2 workers |
| String workerName2 = _vmwareMgr.composeWorkerName(); |
| long checkPointId2 = _checkPointMgr.pushCheckPoint(new VmwareCleanupMaid(hostDetails.get("guid"), workerName2)); |
| cmd.setContextParam("worker2", workerName2); |
| cmd.setContextParam("checkpoint2", String.valueOf(checkPointId2)); |
| } |
|
|
| return cmdTarget.first().getId();
|
| }
|
| }
|
|
|
| return hostId;
|
| } |
| |
| public boolean trackVmHostChange() { |
| return true; |
| } |
|
|
| private static String resolveNameInGuid(String guid) {
|
| String tokens[] = guid.split("@");
|
| assert(tokens.length == 2);
|
|
|
| String vCenterIp = NetUtils.resolveToIp(tokens[1]);
|
| if(vCenterIp == null) {
|
| s_logger.error("Fatal : unable to resolve vCenter address " + tokens[1] + ", please check your DNS configuration");
|
| return guid;
|
| }
|
|
|
| if(vCenterIp.equals(tokens[1]))
|
| return guid;
|
|
|
| return tokens[0] + "@" + vCenterIp;
|
| }
|
| }
|