mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
Merge pull request #1873 from Accelerite/dhcpOffloadFix
CLOUDSTACK-9709: Updated the vm ip fetch task to use the correct the …
This commit is contained in:
commit
7434d91614
@ -0,0 +1,82 @@
|
||||
//
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with 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.
|
||||
//
|
||||
|
||||
package com.cloud.hypervisor.kvm.resource.wrapper;
|
||||
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.GetVmIpAddressCommand;
|
||||
import com.cloud.hypervisor.kvm.resource.LibvirtComputingResource;
|
||||
import com.cloud.resource.CommandWrapper;
|
||||
import com.cloud.resource.ResourceWrapper;
|
||||
import com.cloud.utils.net.NetUtils;
|
||||
import com.cloud.utils.script.Script;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
@ResourceWrapper(handles = GetVmIpAddressCommand.class)
|
||||
public final class LibvirtGetVmIpAddressCommandWrapper extends CommandWrapper<GetVmIpAddressCommand, Answer, LibvirtComputingResource> {
|
||||
|
||||
private static final Logger s_logger = Logger.getLogger(LibvirtGetVmIpAddressCommandWrapper.class);
|
||||
|
||||
@Override
|
||||
public Answer execute(final GetVmIpAddressCommand command, final LibvirtComputingResource libvirtComputingResource) {
|
||||
String ip = null;
|
||||
boolean result = false;
|
||||
String networkCidr = command.getVmNetworkCidr();
|
||||
if(!command.isWindows()) {
|
||||
//List all dhcp lease files inside guestVm
|
||||
String leasesList = Script.runSimpleBashScript(new StringBuilder().append("virt-ls ").append(command.getVmName())
|
||||
.append(" /var/lib/dhclient/ | grep .*\\*.leases").toString());
|
||||
if(leasesList != null) {
|
||||
String[] leasesFiles = leasesList.split("\n");
|
||||
for(String leaseFile : leasesFiles){
|
||||
//Read from each dhclient lease file inside guest Vm using virt-cat libguestfs ulitiy
|
||||
String ipAddr = Script.runSimpleBashScript(new StringBuilder().append("virt-cat ").append(command.getVmName())
|
||||
.append(" /var/lib/dhclient/" + leaseFile + " | tail -16 | grep 'fixed-address' | awk '{print $2}' | sed -e 's/;//'").toString());
|
||||
// Check if the IP belongs to the network
|
||||
if((ipAddr != null) && NetUtils.isIpWithtInCidrRange(ipAddr, networkCidr)){
|
||||
ip = ipAddr;
|
||||
break;
|
||||
}
|
||||
s_logger.debug("GetVmIp: "+command.getVmName()+ " Ip: "+ipAddr+" does not belong to network "+networkCidr);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// For windows, read from guest Vm registry using virt-win-reg libguestfs ulitiy. Registry Path: HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\Tcpip\Parameters\Interfaces\<service>\DhcpIPAddress
|
||||
String ipList = Script.runSimpleBashScript(new StringBuilder().append("virt-win-reg --unsafe-printable-strings ").append(command.getVmName())
|
||||
.append(" 'HKEY_LOCAL_MACHINE\\SYSTEM\\ControlSet001\\Services\\Tcpip\\Parameters\\Interfaces' | grep DhcpIPAddress | awk -F : '{print $2}' | sed -e 's/^\"//' -e 's/\"$//'").toString());
|
||||
if(ipList != null) {
|
||||
s_logger.debug("GetVmIp: "+command.getVmName()+ "Ips: "+ipList);
|
||||
String[] ips = ipList.split("\n");
|
||||
for (String ipAddr : ips){
|
||||
// Check if the IP belongs to the network
|
||||
if((ipAddr != null) && NetUtils.isIpWithtInCidrRange(ipAddr, networkCidr)){
|
||||
ip = ipAddr;
|
||||
break;
|
||||
}
|
||||
s_logger.debug("GetVmIp: "+command.getVmName()+ " Ip: "+ipAddr+" does not belong to network "+networkCidr);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(ip != null){
|
||||
result = true;
|
||||
s_logger.debug("GetVmIp: "+command.getVmName()+ " Found Ip: "+ip);
|
||||
}
|
||||
return new Answer(command, result, ip);
|
||||
}
|
||||
}
|
||||
@ -290,6 +290,9 @@ import com.cloud.vm.VirtualMachine;
|
||||
import com.cloud.vm.VirtualMachine.PowerState;
|
||||
import com.cloud.vm.VirtualMachineName;
|
||||
import com.cloud.vm.VmDetailConstants;
|
||||
import com.vmware.vim25.GuestInfo;
|
||||
import com.vmware.vim25.VirtualMachineToolsStatus;
|
||||
import com.cloud.agent.api.GetVmIpAddressCommand;
|
||||
|
||||
public class VmwareResource implements StoragePoolResource, ServerResource, VmwareHostService, VirtualRouterDeployer {
|
||||
private static final Logger s_logger = Logger.getLogger(VmwareResource.class);
|
||||
@ -490,6 +493,8 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
||||
return execute((ScaleVmCommand)cmd);
|
||||
} else if (clz == PvlanSetupCommand.class) {
|
||||
return execute((PvlanSetupCommand)cmd);
|
||||
} else if (clz == GetVmIpAddressCommand.class) {
|
||||
return execute((GetVmIpAddressCommand)cmd);
|
||||
} else if (clz == UnregisterNicCommand.class) {
|
||||
answer = execute((UnregisterNicCommand)cmd);
|
||||
} else {
|
||||
@ -3285,11 +3290,17 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
||||
s_logger.info("Executing resource RebootCommand: " + _gson.toJson(cmd));
|
||||
}
|
||||
|
||||
boolean toolsInstallerMounted = false;
|
||||
VirtualMachineMO vmMo = null;
|
||||
VmwareContext context = getServiceContext();
|
||||
VmwareHypervisorHost hyperHost = getHyperHost(context);
|
||||
try {
|
||||
VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(cmd.getVmName());
|
||||
vmMo = hyperHost.findVmOnHyperHost(cmd.getVmName());
|
||||
if (vmMo != null) {
|
||||
if (vmMo.isToolsInstallerMounted()) {
|
||||
toolsInstallerMounted = true;
|
||||
s_logger.trace("Detected mounted vmware tools installer for :[" + cmd.getVmName() + "]");
|
||||
}
|
||||
try {
|
||||
vmMo.rebootGuest();
|
||||
return new RebootAnswer(cmd, "reboot succeeded", true);
|
||||
@ -3321,6 +3332,15 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
||||
String msg = "RebootCommand failed due to " + VmwareHelper.getExceptionMessage(e);
|
||||
s_logger.error(msg);
|
||||
return new RebootAnswer(cmd, msg, false);
|
||||
} finally {
|
||||
if (toolsInstallerMounted) {
|
||||
try {
|
||||
vmMo.mountToolsInstaller();
|
||||
s_logger.debug("Successfully re-mounted vmware tools installer for :[" + cmd.getVmName() + "]");
|
||||
} catch (Exception e) {
|
||||
s_logger.warn("Unabled to re-mount vmware tools installer for :[" + cmd.getVmName() + "]");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -4430,6 +4450,59 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
|
||||
}
|
||||
|
||||
|
||||
protected Answer execute(GetVmIpAddressCommand cmd) {
|
||||
if (s_logger.isTraceEnabled()) {
|
||||
s_logger.trace("Executing resource command GetVmIpAddressCommand: " + _gson.toJson(cmd));
|
||||
}
|
||||
|
||||
String details = "Unable to find IP Address of VM. ";
|
||||
String vmName = cmd.getVmName();
|
||||
boolean result = false;
|
||||
String ip = null;
|
||||
Answer answer = null;
|
||||
|
||||
VmwareContext context = getServiceContext();
|
||||
VmwareHypervisorHost hyperHost = getHyperHost(context);
|
||||
|
||||
if (vmName == null || vmName.isEmpty()) {
|
||||
details += "Name of instance provided is NULL or empty.";
|
||||
return new Answer(cmd, result, details);
|
||||
}
|
||||
|
||||
try {
|
||||
VirtualMachineMO vmMo = hyperHost.findVmOnHyperHost(vmName);
|
||||
if (vmMo != null) {
|
||||
GuestInfo guestInfo = vmMo.getGuestInfo();
|
||||
VirtualMachineToolsStatus toolsStatus = guestInfo.getToolsStatus();
|
||||
if (toolsStatus == VirtualMachineToolsStatus.TOOLS_NOT_INSTALLED) {
|
||||
details += "Vmware tools not installed.";
|
||||
} else {
|
||||
ip = guestInfo.getIpAddress();
|
||||
if (ip != null) {
|
||||
result = true;
|
||||
}
|
||||
details = ip;
|
||||
}
|
||||
} else {
|
||||
details += "VM " + vmName + " no longer exists on vSphere host: " + hyperHost.getHyperHostName();
|
||||
s_logger.info(details);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
if (e instanceof RemoteException) {
|
||||
s_logger.warn("Encounter remote exception to vCenter, invalidate VMware session context");
|
||||
invalidateServiceContext();
|
||||
}
|
||||
details += "Encountered exception : " + VmwareHelper.getExceptionMessage(e);
|
||||
s_logger.error(details);
|
||||
}
|
||||
|
||||
answer = new Answer(cmd, result, details);
|
||||
if (s_logger.isTraceEnabled()) {
|
||||
s_logger.trace("Returning GetVmIpAddressAnswer: " + _gson.toJson(answer));
|
||||
}
|
||||
return answer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PrimaryStorageDownloadAnswer execute(PrimaryStorageDownloadCommand cmd) {
|
||||
if (s_logger.isInfoEnabled()) {
|
||||
|
||||
@ -477,6 +477,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
protected IpAddressManager _ipAddrMgr;
|
||||
|
||||
protected ScheduledExecutorService _executor = null;
|
||||
protected ScheduledExecutorService _vmIpFetchExecutor = null;
|
||||
protected int _expungeInterval;
|
||||
protected int _expungeDelay;
|
||||
protected boolean _dailyOrHourly = false;
|
||||
@ -514,6 +515,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
static final ConfigKey<Integer> VmIpFetchThreadPoolMax = new ConfigKey<Integer>("Advanced", Integer.class, "externaldhcp.vmipFetch.threadPool.max", "10",
|
||||
"number of threads for fetching vms ip address", true);
|
||||
|
||||
static final ConfigKey<Integer> VmIpFetchTaskWorkers = new ConfigKey<Integer>("Advanced", Integer.class, "externaldhcp.vmipfetchtask.workers", "10",
|
||||
"number of worker threads for vm ip fetch task ", true);
|
||||
|
||||
|
||||
@Override
|
||||
public UserVmVO getVirtualMachine(long vmId) {
|
||||
@ -1947,6 +1951,11 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
|
||||
_executor = Executors.newScheduledThreadPool(wrks, new NamedThreadFactory("UserVm-Scavenger"));
|
||||
|
||||
String vmIpWorkers = configs.get(VmIpFetchTaskWorkers.value());
|
||||
int vmipwrks = NumbersUtil.parseInt(vmIpWorkers, 10);
|
||||
|
||||
_vmIpFetchExecutor = Executors.newScheduledThreadPool(vmipwrks, new NamedThreadFactory("UserVm-ipfetch"));
|
||||
|
||||
String aggregationRange = configs.get("usage.stats.job.aggregation.range");
|
||||
int _usageAggregationRange = NumbersUtil.parseInt(aggregationRange, 1440);
|
||||
int HOURLY_TIME = 60;
|
||||
@ -1966,7 +1975,9 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
String value = _configDao.getValue(Config.SetVmInternalNameUsingDisplayName.key());
|
||||
_instanceNameFlag = (value == null) ? false : Boolean.parseBoolean(value);
|
||||
|
||||
_scaleRetry = NumbersUtil.parseInt(configs.get(Config.ScaleRetry.key()), 2);
|
||||
_scaleRetry = NumbersUtil.parseInt(configs.get(Config.ScaleRetry.key()), 2);
|
||||
|
||||
_vmIpFetchThreadExecutor = Executors.newFixedThreadPool(VmIpFetchThreadPoolMax.value(), new NamedThreadFactory("vmIpFetchThread"));
|
||||
|
||||
s_logger.info("User VM Manager is configured.");
|
||||
|
||||
@ -1981,7 +1992,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
@Override
|
||||
public boolean start() {
|
||||
_executor.scheduleWithFixedDelay(new ExpungeTask(), _expungeInterval, _expungeInterval, TimeUnit.SECONDS);
|
||||
_executor.scheduleWithFixedDelay(new VmIpFetchTask(), VmIpFetchWaitInterval.value(), VmIpFetchWaitInterval.value(), TimeUnit.SECONDS);
|
||||
_vmIpFetchExecutor.scheduleWithFixedDelay(new VmIpFetchTask(), VmIpFetchWaitInterval.value(), VmIpFetchWaitInterval.value(), TimeUnit.SECONDS);
|
||||
loadVmDetailsInMapForExternalDhcpIp();
|
||||
return true;
|
||||
}
|
||||
@ -2015,6 +2026,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
@Override
|
||||
public boolean stop() {
|
||||
_executor.shutdown();
|
||||
_vmIpFetchExecutor.shutdown();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2599,7 +2611,21 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
throw new InvalidParameterValueException("Unable to find service offering: " + serviceOfferingId + " corresponding to the vm");
|
||||
}
|
||||
|
||||
return rebootVirtualMachine(CallContext.current().getCallingUserId(), vmId);
|
||||
UserVm userVm = rebootVirtualMachine(CallContext.current().getCallingUserId(), vmId);
|
||||
if (userVm != null ) {
|
||||
// update the vmIdCountMap if the vm is in advanced shared network with out services
|
||||
final List<NicVO> nics = _nicDao.listByVmId(vmId);
|
||||
for (NicVO nic : nics) {
|
||||
Network network = _networkModel.getNetwork(nic.getNetworkId());
|
||||
if (_networkModel.isSharedNetworkWithoutServices(network.getId())) {
|
||||
s_logger.debug("Adding vm " +vmId +" nic id "+ nic.getId() +" into vmIdCountMap as part of vm " +
|
||||
"reboot for vm ip fetch ");
|
||||
vmIdCountMap.put(nic.getId(), new VmAndCountDetails(nic.getInstanceId(), VmIpFetchTrialMax.value()));
|
||||
}
|
||||
}
|
||||
return userVm;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -3821,7 +3847,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean finalizeStart(VirtualMachineProfile profile, long hostId, Commands cmds, ReservationContext context) {
|
||||
public boolean finalizeStart(VirtualMachineProfile profile, long hostId, Commands cmds, ReservationContext context) {
|
||||
UserVmVO vm = _vmDao.findById(profile.getId());
|
||||
|
||||
Answer[] answersToCmds = cmds.getAnswers();
|
||||
@ -3909,6 +3935,21 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
}
|
||||
}
|
||||
|
||||
final VirtualMachineProfile vmProfile = profile;
|
||||
Transaction.execute(new TransactionCallbackNoReturn() {
|
||||
@Override
|
||||
public void doInTransactionWithoutResult(TransactionStatus status) {
|
||||
final UserVmVO vm = _vmDao.findById(vmProfile.getId());
|
||||
final List<NicVO> nics = _nicDao.listByVmId(vm.getId());
|
||||
for (NicVO nic : nics) {
|
||||
Network network = _networkModel.getNetwork(nic.getNetworkId());
|
||||
if (_networkModel.isSharedNetworkWithoutServices(network.getId())) {
|
||||
vmIdCountMap.put(nic.getId(), new VmAndCountDetails(nic.getInstanceId(), VmIpFetchTrialMax.value()));
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -5848,7 +5889,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
||||
|
||||
@Override
|
||||
public ConfigKey<?>[] getConfigKeys() {
|
||||
return new ConfigKey<?>[] {EnableDynamicallyScaleVm, AllowUserExpungeRecoverVm, VmIpFetchWaitInterval, VmIpFetchTrialMax, VmIpFetchThreadPoolMax};
|
||||
return new ConfigKey<?>[] {EnableDynamicallyScaleVm, AllowUserExpungeRecoverVm, VmIpFetchWaitInterval, VmIpFetchTrialMax, VmIpFetchThreadPoolMax, VmIpFetchTaskWorkers};
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@ -751,6 +751,13 @@ public class VirtualMachineMO extends BaseMO {
|
||||
return (VirtualMachineConfigInfo)_context.getVimClient().getDynamicProperty(_mor, "config");
|
||||
}
|
||||
|
||||
public boolean isToolsInstallerMounted() throws Exception {
|
||||
return _context.getVimClient().getDynamicProperty(_mor, "runtime.toolsInstallerMounted");
|
||||
}
|
||||
public GuestInfo getGuestInfo() throws Exception {
|
||||
return (GuestInfo)_context.getVimClient().getDynamicProperty(_mor, "guest");
|
||||
}
|
||||
|
||||
public VirtualMachineConfigSummary getConfigSummary() throws Exception {
|
||||
return (VirtualMachineConfigSummary)_context.getVimClient().getDynamicProperty(_mor, "summary.config");
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user