You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ja...@apache.org on 2015/05/28 13:59:20 UTC
[3/9] git commit: updated refs/heads/master to b616522
CLOUDSTACK-8324: Added vm ip fetch logic
Project: http://git-wip-us.apache.org/repos/asf/cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/cloudstack/commit/733ac2b7
Tree: http://git-wip-us.apache.org/repos/asf/cloudstack/tree/733ac2b7
Diff: http://git-wip-us.apache.org/repos/asf/cloudstack/diff/733ac2b7
Branch: refs/heads/master
Commit: 733ac2b728f4eda39b282fc03ef222cf23d546e1
Parents: 70934e8
Author: Jayapal <ja...@apache.org>
Authored: Wed May 20 10:24:44 2015 +0530
Committer: Jayapal <ja...@apache.org>
Committed: Thu May 28 15:42:08 2015 +0530
----------------------------------------------------------------------
api/src/com/cloud/event/EventTypes.java | 1 +
.../cloud/agent/api/GetVmIpAddressCommand.java | 50 +++++
.../cloud/agent/api/routing/VmDataCommand.java | 5 +
.../src/com/cloud/network/dao/NetworkDao.java | 2 +
.../com/cloud/network/dao/NetworkDaoImpl.java | 8 +
server/src/com/cloud/vm/UserVmManagerImpl.java | 225 ++++++++++++++++++-
.../com/cloud/vpc/dao/MockNetworkDaoImpl.java | 5 +
7 files changed, 295 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/733ac2b7/api/src/com/cloud/event/EventTypes.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/event/EventTypes.java b/api/src/com/cloud/event/EventTypes.java
index 78236fa..870c7e7 100644
--- a/api/src/com/cloud/event/EventTypes.java
+++ b/api/src/com/cloud/event/EventTypes.java
@@ -523,6 +523,7 @@ public class EventTypes {
public static final String EVENT_NIC_SECONDARY_IP_ASSIGN = "NIC.SECONDARY.IP.ASSIGN";
public static final String EVENT_NIC_SECONDARY_IP_UNASSIGN = "NIC.SECONDARY.IP.UNASSIGN";
public static final String EVENT_NIC_SECONDARY_IP_CONFIGURE = "NIC.SECONDARY.IP.CONFIGURE";
+ public static final String EVENT_NETWORK_EXTERNAL_DHCP_VM_IPFETCH = "EXTERNAL.DHCP.VM.IP.FETCH";
//Usage related events
public static final String EVENT_USAGE_REMOVE_USAGE_RECORDS = "USAGE.REMOVE.USAGE.RECORDS";
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/733ac2b7/core/src/com/cloud/agent/api/GetVmIpAddressCommand.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/GetVmIpAddressCommand.java b/core/src/com/cloud/agent/api/GetVmIpAddressCommand.java
new file mode 100644
index 0000000..a9c7413
--- /dev/null
+++ b/core/src/com/cloud/agent/api/GetVmIpAddressCommand.java
@@ -0,0 +1,50 @@
+//
+// 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.agent.api;
+
+public class GetVmIpAddressCommand extends Command {
+
+ String vmName;
+ String vmNetworkCidr;
+ boolean windows = false;
+
+ public GetVmIpAddressCommand(String vmName, String vmNetworkCidr, boolean windows) {
+ this.vmName = vmName;
+ this.windows = windows;
+ this.vmNetworkCidr = vmNetworkCidr;
+ }
+
+ @Override
+ public boolean executeInSequence() {
+ return false;
+ }
+
+ public String getVmName(){
+ return vmName;
+ }
+
+ public boolean isWindows(){
+ return windows;
+ }
+
+ public String getVmNetworkCidr() {
+ return vmNetworkCidr;
+ }
+}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/733ac2b7/core/src/com/cloud/agent/api/routing/VmDataCommand.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/api/routing/VmDataCommand.java b/core/src/com/cloud/agent/api/routing/VmDataCommand.java
index 733866c..c74c7cf 100644
--- a/core/src/com/cloud/agent/api/routing/VmDataCommand.java
+++ b/core/src/com/cloud/agent/api/routing/VmDataCommand.java
@@ -56,6 +56,11 @@ public class VmDataCommand extends NetworkElementCommand {
this.executeInSequence = executeInSequence;
}
+ public VmDataCommand(String vmName) {
+ this.vmName = vmName;
+ this.vmData = new ArrayList<String[]>();
+ }
+
public String getVmIpAddress() {
return vmIpAddress;
}
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/733ac2b7/engine/schema/src/com/cloud/network/dao/NetworkDao.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/network/dao/NetworkDao.java b/engine/schema/src/com/cloud/network/dao/NetworkDao.java
index 037f776..49c8015 100644
--- a/engine/schema/src/com/cloud/network/dao/NetworkDao.java
+++ b/engine/schema/src/com/cloud/network/dao/NetworkDao.java
@@ -31,6 +31,8 @@ public interface NetworkDao extends GenericDao<NetworkVO, Long>, StateDao<State,
List<NetworkVO> listByOwner(long ownerId);
+ List<NetworkVO> listByGuestType(GuestType type);
+
List<NetworkVO> listBy(long accountId, long offeringId, long dataCenterId);
List<NetworkVO> listBy(long accountId, long dataCenterId, String cidr, boolean skipVpc);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/733ac2b7/engine/schema/src/com/cloud/network/dao/NetworkDaoImpl.java
----------------------------------------------------------------------
diff --git a/engine/schema/src/com/cloud/network/dao/NetworkDaoImpl.java b/engine/schema/src/com/cloud/network/dao/NetworkDaoImpl.java
index 433eded..3c79985 100644
--- a/engine/schema/src/com/cloud/network/dao/NetworkDaoImpl.java
+++ b/engine/schema/src/com/cloud/network/dao/NetworkDaoImpl.java
@@ -270,6 +270,14 @@ public class NetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implements N
return listBy(sc, null);
}
+ @Override
+ public List<NetworkVO> listByGuestType(Network.GuestType type) {
+ SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
+ sc.setParameters("guestType", type);
+ return listBy(sc, null);
+ }
+
+
public List<NetworkVO> findBy(final TrafficType trafficType, final Mode mode, final BroadcastDomainType broadcastType, final long networkOfferingId, final long dataCenterId) {
final SearchCriteria<NetworkVO> sc = AllFieldsSearch.create();
sc.setParameters("trafficType", trafficType);
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/733ac2b7/server/src/com/cloud/vm/UserVmManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/vm/UserVmManagerImpl.java b/server/src/com/cloud/vm/UserVmManagerImpl.java
index a413d11..1661390 100644
--- a/server/src/com/cloud/vm/UserVmManagerImpl.java
+++ b/server/src/com/cloud/vm/UserVmManagerImpl.java
@@ -27,8 +27,10 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;
import javax.ejb.Local;
@@ -97,6 +99,7 @@ import com.cloud.agent.api.GetVmDiskStatsCommand;
import com.cloud.agent.api.GetVmStatsAnswer;
import com.cloud.agent.api.GetVmStatsCommand;
import com.cloud.agent.api.PvlanSetupCommand;
+import com.cloud.agent.api.GetVmIpAddressCommand;
import com.cloud.agent.api.StartAnswer;
import com.cloud.agent.api.VmDiskStatsEntry;
import com.cloud.agent.api.VmStatsEntry;
@@ -129,9 +132,12 @@ import com.cloud.deploy.DeploymentPlanningManager;
import com.cloud.deploy.PlannerHostReservationVO;
import com.cloud.deploy.dao.PlannerHostReservationDao;
import com.cloud.domain.DomainVO;
+import com.cloud.domain.Domain;
import com.cloud.domain.dao.DomainDao;
import com.cloud.event.ActionEvent;
import com.cloud.event.EventTypes;
+import com.cloud.event.ActionEventUtils;
+import com.cloud.event.ActionEventUtils;
import com.cloud.event.UsageEventUtils;
import com.cloud.event.UsageEventVO;
import com.cloud.event.dao.UsageEventDao;
@@ -475,11 +481,14 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
protected int _expungeDelay;
protected boolean _dailyOrHourly = false;
private int capacityReleaseInterval;
+ ExecutorService _vmIpFetchThreadExecutor;
+
protected String _instance;
protected String _zone;
protected boolean _instanceNameFlag;
protected int _scaleRetry;
+ protected Map<Long, VmAndCountDetails> vmIdCountMap = new ConcurrentHashMap<>();
@Inject
ConfigurationDao _configDao;
@@ -496,6 +505,16 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
@Inject
ManagementService _mgr;
+ static final ConfigKey<Integer> VmIpFetchWaitInterval = new ConfigKey<Integer>("Advanced", Integer.class, "externaldhcp.vmip.retrieval.interval", "180",
+ "Wait Interval (in seconds) for shared network vm dhcp ip addr fetch for next iteration ", true);
+
+ static final ConfigKey<Integer> VmIpFetchTrialMax = new ConfigKey<Integer>("Advanced", Integer.class, "externaldhcp.vmip.max.retry", "10",
+ "The max number of retrieval times for shared entwork vm dhcp ip fetch, in case of failures", true);
+
+ 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);
+
+
@Override
public UserVmVO getVirtualMachine(long vmId) {
return _vmDao.findById(vmId);
@@ -524,6 +543,122 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
_resourceLimitMgr.decrementResourceCount(accountId, ResourceType.memory, displayVm, memory);
}
+ public class VmAndCountDetails {
+ long vmId;
+ int retrievalCount = VmIpFetchTrialMax.value();
+
+
+ public VmAndCountDetails() {
+ }
+
+ public VmAndCountDetails (long vmId, int retrievalCount) {
+ this.vmId = vmId;
+ this.retrievalCount = retrievalCount;
+ }
+
+ public VmAndCountDetails (long vmId) {
+ this.vmId = vmId;
+ }
+
+ public int getRetrievalCount() {
+ return retrievalCount;
+ }
+
+ public void setRetrievalCount(int retrievalCount) {
+ this.retrievalCount = retrievalCount;
+ }
+
+ public long getVmId() {
+ return vmId;
+ }
+
+ public void setVmId(long vmId) {
+ this.vmId = vmId;
+ }
+
+ public void decrementCount() {
+ this.retrievalCount--;
+
+ }
+ }
+
+ protected class VmIpAddrFetchThread extends ManagedContextRunnable {
+
+
+ long nicId;
+ long vmId;
+ String vmName;
+ boolean isWindows;
+ Long hostId;
+ String networkCidr;
+
+ public VmIpAddrFetchThread() {
+ }
+
+ public VmIpAddrFetchThread(long vmId, long nicId, String instanceName, boolean windows, Long hostId, String networkCidr) {
+ this.vmId = vmId;
+ this.nicId = nicId;
+ this.vmName = instanceName;
+ this.isWindows = windows;
+ this.hostId = hostId;
+ this.networkCidr = networkCidr;
+ }
+
+ @Override
+ protected void runInContext() {
+ GetVmIpAddressCommand cmd = new GetVmIpAddressCommand(vmName, networkCidr, isWindows);
+ boolean decrementCount = true;
+
+ try {
+ s_logger.debug("Trying for vm "+ vmId +" nic Id "+nicId +" ip retrieval ...");
+ Answer answer = _agentMgr.send(hostId, cmd);
+ NicVO nic = _nicDao.findById(nicId);
+ if (answer.getResult()) {
+ String vmIp = answer.getDetails();
+
+ if (NetUtils.isValidIp(vmIp)) {
+ // set this vm ip addr in vm nic.
+ if (nic != null) {
+ nic.setIp4Address(vmIp);
+ _nicDao.update(nicId, nic);
+ s_logger.debug("Vm "+ vmId +" IP "+vmIp +" got retrieved successfully");
+ vmIdCountMap.remove(nicId);
+ decrementCount = false;
+ ActionEventUtils.onActionEvent(User.UID_SYSTEM, Account.ACCOUNT_ID_SYSTEM,
+ Domain.ROOT_DOMAIN, EventTypes.EVENT_NETWORK_EXTERNAL_DHCP_VM_IPFETCH,
+ "VM " + vmId + " nic id " + nicId + " ip address " + vmIp + " got fetched successfully");
+ }
+ }
+ } else {
+ //previously vm has ip and nic table has ip address. After vm restart or stop/start
+ //if vm doesnot get the ip then set the ip in nic table to null
+ if (nic.getIp4Address() != null) {
+ nic.setIp4Address(null);
+ _nicDao.update(nicId, nic);
+ }
+ if (answer.getDetails() != null) {
+ s_logger.debug("Failed to get vm ip for Vm "+ vmId + answer.getDetails());
+ }
+ }
+ } catch (OperationTimedoutException e) {
+ s_logger.warn("Timed Out", e);
+ } catch (AgentUnavailableException e) {
+ s_logger.warn("Agent Unavailable ", e);
+ } finally {
+ if (decrementCount) {
+ VmAndCountDetails vmAndCount = vmIdCountMap.get(nicId);
+ vmAndCount.decrementCount();
+ s_logger.debug("Ip is not retrieved for VM " + vmId +" nic "+nicId + " ... decremented count to "+vmAndCount.getRetrievalCount());
+ vmIdCountMap.put(nicId, vmAndCount);
+ }
+ }
+ }
+ }
+
+
+
+
+
@Override
@ActionEvent(eventType = EventTypes.EVENT_VM_RESETPASSWORD, eventDescription = "resetting Vm password", async = true)
public UserVm resetVMPassword(ResetVMPasswordCmd cmd, String password) throws ResourceUnavailableException, InsufficientCapacityException {
@@ -1716,9 +1851,37 @@ 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);
+ loadVmDetailsInMapForExternalDhcpIp();
return true;
}
+ private void loadVmDetailsInMapForExternalDhcpIp() {
+
+ List<NetworkVO> networks = _networkDao.listByGuestType(Network.GuestType.Shared);
+
+ for (NetworkVO network: networks) {
+ if(_networkModel.isSharedNetworkWithoutServices(network.getId())) {
+ List<NicVO> nics = _nicDao.listByNetworkId(network.getId());
+
+ for (NicVO nic : nics) {
+
+ if (nic.getIp4Address() == null) {
+ long nicId = nic.getId();
+ long vmId = nic.getInstanceId();
+ VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId);
+
+ // only load running vms. For stopped vms get loaded on starting
+ if (vmInstance.getState() == State.Running) {
+ VmAndCountDetails vmAndCount = new VmAndCountDetails(vmId, VmIpFetchTrialMax.value());
+ vmIdCountMap.put(nicId, vmAndCount);
+ }
+ }
+ }
+ }
+ }
+ }
+
@Override
public boolean stop() {
_executor.shutdown();
@@ -1872,6 +2035,66 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
}
}
+
+
+ protected class VmIpFetchTask extends ManagedContextRunnable {
+
+ public VmIpFetchTask() {
+ GlobalLock scanLock = GlobalLock.getInternLock("vmIpFetch");
+ }
+
+ @Override
+ protected void runInContext() {
+ GlobalLock scanLock = GlobalLock.getInternLock("vmIpFetch");
+
+ try {
+ if (scanLock.lock(ACQUIRE_GLOBAL_LOCK_TIMEOUT_FOR_COOPERATION)) {
+ try {
+
+ for (Entry<Long, VmAndCountDetails> entry: vmIdCountMap.entrySet()) {
+ long nicId = entry.getKey();
+ VmAndCountDetails vmIdAndCount = entry.getValue();
+ long vmId = vmIdAndCount.getVmId();
+
+ if (vmIdAndCount.getRetrievalCount() <= 0) {
+ vmIdCountMap.remove(nicId);
+ s_logger.debug("Vm " + vmId +" nic "+nicId + " count is zero .. removing vm nic from map ");
+
+ ActionEventUtils.onActionEvent(User.UID_SYSTEM, Account.ACCOUNT_ID_SYSTEM,
+ Domain.ROOT_DOMAIN, EventTypes.EVENT_NETWORK_EXTERNAL_DHCP_VM_IPFETCH,
+ "VM " + vmId + " nic id "+ nicId + " ip addr fetch failed ");
+
+ continue;
+ }
+
+
+ UserVm userVm = _vmDao.findById(vmId);
+ VMInstanceVO vmInstance = _vmInstanceDao.findById(vmId);
+ NicVO nicVo = _nicDao.findById(nicId);
+ NetworkVO network = _networkDao.findById(nicVo.getNetworkId());
+
+ VirtualMachineProfile vmProfile = new VirtualMachineProfileImpl(userVm);
+ VirtualMachine vm = vmProfile.getVirtualMachine();
+ boolean isWindows = _guestOSCategoryDao.findById(_guestOSDao.findById(vm.getGuestOSId()).getCategoryId()).getName().equalsIgnoreCase("Windows");
+
+ _vmIpFetchThreadExecutor.execute(new VmIpAddrFetchThread(vmId, nicId, vmInstance.getInstanceName(),
+ isWindows, vm.getHostId(), network.getCidr()));
+
+ }
+ } catch (Exception e) {
+ s_logger.error("Caught the Exception in VmIpFetchTask", e);
+ } finally {
+ scanLock.unlock();
+ }
+ }
+ } finally {
+ scanLock.releaseRef();
+ }
+
+ }
+ }
+
+
protected class ExpungeTask extends ManagedContextRunnable {
public ExpungeTask() {
}
@@ -5045,7 +5268,7 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
@Override
public ConfigKey<?>[] getConfigKeys() {
- return new ConfigKey<?>[] {EnableDynamicallyScaleVm};
+ return new ConfigKey<?>[] {EnableDynamicallyScaleVm, VmIpFetchWaitInterval, VmIpFetchTrialMax, VmIpFetchThreadPoolMax};
}
@Override
http://git-wip-us.apache.org/repos/asf/cloudstack/blob/733ac2b7/server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java
----------------------------------------------------------------------
diff --git a/server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java b/server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java
index cf4fc35..89f15d5 100644
--- a/server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java
+++ b/server/test/com/cloud/vpc/dao/MockNetworkDaoImpl.java
@@ -45,6 +45,11 @@ public class MockNetworkDaoImpl extends GenericDaoBase<NetworkVO, Long> implemen
return null;
}
+ @Override
+ public List<NetworkVO> listByGuestType(GuestType type) {
+ return null;
+ }
+
/* (non-Javadoc)
* @see com.cloud.network.dao.NetworkDao#listBy(long, long, long)
*/