This commit is contained in:
Sebastien Goasguen 2014-01-15 11:16:31 +01:00
commit 264f5172be
27 changed files with 419 additions and 172 deletions

View File

@ -40,7 +40,8 @@ public interface PhysicalNetwork extends Identity, InternalIdentity {
VNS,
MIDO,
SSP,
VXLAN;
VXLAN,
L3VPN;
}
public enum BroadcastDomainRange {

View File

@ -62,6 +62,7 @@ import org.apache.cloudstack.framework.jobs.impl.AsyncJobVO;
import org.apache.cloudstack.framework.jobs.impl.OutcomeImpl;
import org.apache.cloudstack.framework.jobs.impl.VmWorkJobVO;
import org.apache.cloudstack.framework.messagebus.MessageBus;
import org.apache.cloudstack.framework.messagebus.MessageDispatcher;
import org.apache.cloudstack.framework.messagebus.MessageHandler;
import org.apache.cloudstack.jobs.JobInfo;
import org.apache.cloudstack.managed.context.ManagedContextRunnable;
@ -575,6 +576,10 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
_agentMgr.registerForHostEvents(this, true, true, true);
if (VmJobEnabled.value()) {
_messageBus.subscribe(VirtualMachineManager.Topics.VM_POWER_STATE, MessageDispatcher.getDispatcher(this));
}
return true;
}
@ -3815,7 +3820,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
//
@MessageHandler(topic = Topics.VM_POWER_STATE)
private void HandlePownerStateReport(Object target, String subject, String senderAddress, Object args) {
private void HandlePowerStateReport(String subject, String senderAddress, Object args) {
assert(args != null);
Long vmId = (Long)args;
@ -3835,7 +3840,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
break;
// PowerUnknown shouldn't be reported, it is a derived
// VM power state from host state (host un-reachable
// VM power state from host state (host un-reachable)
case PowerUnknown :
default :
assert(false);
@ -3845,8 +3850,9 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
s_logger.warn("VM " + vmId + " no longer exists when processing VM state report");
}
} else {
// TODO, do job wake-up signalling, since currently async job wake-up is not in use
// we will skip it for nows
// reset VM power state tracking so that we won't lost signal when VM has
// been translated to
_vmDao.resetVmPowerStateTracking(vmId);
}
}
@ -3921,6 +3927,7 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
switch(vm.getState()) {
case Starting :
case Stopping :
case Running:
case Stopped :
case Migrating :
try {
@ -3933,7 +3940,6 @@ public class VirtualMachineManagerImpl extends ManagerBase implements VirtualMac
// TODO: we need to forcely release all resource allocation
break;
case Running :
case Destroyed :
case Expunging :
break;

View File

@ -5,7 +5,7 @@
// 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,
@ -21,11 +21,13 @@ import java.util.Map;
import com.cloud.agent.api.HostVmStateReportEntry;
public interface VirtualMachinePowerStateSync {
void resetHostSyncState(long hostId);
void processHostVmStateReport(long hostId, Map<String, HostVmStateReportEntry> report);
// to adapt legacy ping report
void processHostVmStatePingReport(long hostId, Map<String, HostVmStateReportEntry> report);
Map<Long, VirtualMachine.PowerState> convertVmStateReport(Map<String, HostVmStateReportEntry> states);
}

View File

@ -35,22 +35,22 @@ public class VirtualMachinePowerStateSyncImpl implements VirtualMachinePowerStat
@Inject MessageBus _messageBus;
@Inject VMInstanceDao _instanceDao;
@Inject VirtualMachineManager _vmMgr;
public VirtualMachinePowerStateSyncImpl() {
}
@Override
public void resetHostSyncState(long hostId) {
s_logger.info("Reset VM power state sync for host: " + hostId);
_instanceDao.resetHostPowerStateTracking(hostId);
}
@Override
public void processHostVmStateReport(long hostId, Map<String, HostVmStateReportEntry> report) {
if(s_logger.isDebugEnabled())
s_logger.debug("Process host VM state report from ping process. host: " + hostId);
Map<Long, VirtualMachine.PowerState> translatedInfo = convertToInfos(report);
Map<Long, VirtualMachine.PowerState> translatedInfo = convertVmStateReport(report);
processReport(hostId, translatedInfo);
}
@ -58,39 +58,41 @@ public class VirtualMachinePowerStateSyncImpl implements VirtualMachinePowerStat
public void processHostVmStatePingReport(long hostId, Map<String, HostVmStateReportEntry> report) {
if(s_logger.isDebugEnabled())
s_logger.debug("Process host VM state report from ping process. host: " + hostId);
Map<Long, VirtualMachine.PowerState> translatedInfo = convertToInfos(report);
Map<Long, VirtualMachine.PowerState> translatedInfo = convertVmStateReport(report);
processReport(hostId, translatedInfo);
}
private void processReport(long hostId, Map<Long, VirtualMachine.PowerState> translatedInfo) {
for(Map.Entry<Long, VirtualMachine.PowerState> entry : translatedInfo.entrySet()) {
if(s_logger.isDebugEnabled())
s_logger.debug("VM state report. host: " + hostId + ", vm id: " + entry.getKey() + ", power state: " + entry.getValue());
if(_instanceDao.updatePowerState(entry.getKey(), hostId, entry.getValue())) {
if(s_logger.isDebugEnabled())
s_logger.debug("VM state report is updated. host: " + hostId + ", vm id: " + entry.getKey() + ", power state: " + entry.getValue());
_messageBus.publish(null, VirtualMachineManager.Topics.VM_POWER_STATE, PublishScope.GLOBAL, entry.getKey());
} else {
if (s_logger.isDebugEnabled())
s_logger.debug("VM power state does not change, skip DB writing. vm id: " + entry.getKey());
}
}
}
private Map<Long, VirtualMachine.PowerState> convertToInfos(Map<String, HostVmStateReportEntry> states) {
@Override
public Map<Long, VirtualMachine.PowerState> convertVmStateReport(Map<String, HostVmStateReportEntry> states) {
final HashMap<Long, VirtualMachine.PowerState> map = new HashMap<Long, VirtualMachine.PowerState>();
if (states == null) {
return map;
}
for (Map.Entry<String, HostVmStateReportEntry> entry : states.entrySet()) {
VMInstanceVO vm = findVM(entry.getKey());
if(vm != null) {
map.put(vm.getId(), entry.getValue().getState());
break;
} else {
s_logger.info("Unable to find matched VM in CloudStack DB. name: " + entry.getKey());
}
@ -98,7 +100,7 @@ public class VirtualMachinePowerStateSyncImpl implements VirtualMachinePowerStat
return map;
}
private VMInstanceVO findVM(String vmName) {
return _instanceDao.findVMByInstanceName(vmName);
}

View File

@ -63,6 +63,49 @@ public class Upgrade421to430 implements DbUpgrade {
@Override
public void performDataMigration(Connection conn) {
encryptLdapConfigParams(conn);
upgradeMemoryOfSsvmOffering(conn);
}
private void upgradeMemoryOfSsvmOffering(Connection conn) {
PreparedStatement updatePstmt = null;
PreparedStatement selectPstmt = null;
ResultSet selectResultSet = null;
int newRamSize = 512; //512MB
long serviceOfferingId = 0;
/**
* Pick first row in service_offering table which has system vm type as secondary storage vm. User added offerings would start from 2nd row onwards.
* We should not update/modify any user-defined offering.
*/
try {
selectPstmt = conn.prepareStatement("SELECT id FROM `cloud`.`service_offering` WHERE vm_type='secondarystoragevm'");
updatePstmt = conn.prepareStatement("UPDATE `cloud`.`service_offering` SET ram_size=? WHERE id=?'");
selectResultSet = selectPstmt.executeQuery();
if(selectResultSet.next()) {
serviceOfferingId = selectResultSet.getLong("id");
}
updatePstmt.setInt(1, newRamSize);
updatePstmt.setLong(2, serviceOfferingId);
updatePstmt.executeUpdate();
} catch (SQLException e) {
throw new CloudRuntimeException("Unable to upgrade ram_size of service offering for secondary storage vm. ", e);
} finally {
try {
if (selectPstmt != null) {
selectPstmt.close();
}
if (selectResultSet != null) {
selectResultSet.close();
}
if (updatePstmt != null) {
updatePstmt.close();
}
} catch (SQLException e) {
}
}
s_logger.debug("Done upgrading RAM for service offering of Secondary Storage VM to " + newRamSize);
}
private void encryptLdapConfigParams(Connection conn) {

View File

@ -70,6 +70,8 @@ public interface VMInstanceDao extends GenericDao<VMInstanceVO, Long>, StateDao<
List<VMInstanceVO> findVMInTransition(Date time, State... states);
List<VMInstanceVO> listByHostAndState(long hostId, State... states);
List<VMInstanceVO> listByTypes(VirtualMachine.Type... types);
VMInstanceVO findByIdTypes(long id, VirtualMachine.Type... types);
@ -123,8 +125,8 @@ public interface VMInstanceDao extends GenericDao<VMInstanceVO, Long>, StateDao<
List<VMInstanceVO> listStartingWithNoHostId();
boolean updatePowerState(long instanceId, long powerHostId, VirtualMachine.PowerState powerState);
void resetVmPowerStateTracking(long instanceId);
void resetHostPowerStateTracking(long hostId);
}

View File

@ -49,7 +49,11 @@ import com.cloud.utils.db.SearchBuilder;
import com.cloud.utils.db.SearchCriteria;
import com.cloud.utils.db.SearchCriteria.Func;
import com.cloud.utils.db.SearchCriteria.Op;
import com.cloud.utils.db.Transaction;
import com.cloud.utils.db.TransactionCallback;
import com.cloud.utils.db.TransactionCallbackNoReturn;
import com.cloud.utils.db.TransactionLegacy;
import com.cloud.utils.db.TransactionStatus;
import com.cloud.utils.db.UpdateBuilder;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.vm.NicVO;
@ -65,7 +69,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
public static final Logger s_logger = Logger.getLogger(VMInstanceDaoImpl.class);
private static final int MAX_CONSECUTIVE_SAME_STATE_UPDATE_COUNT = 3;
protected SearchBuilder<VMInstanceVO> VMClusterSearch;
protected SearchBuilder<VMInstanceVO> LHVMClusterSearch;
protected SearchBuilder<VMInstanceVO> IdStatesSearch;
@ -77,6 +81,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
protected SearchBuilder<VMInstanceVO> TypesSearch;
protected SearchBuilder<VMInstanceVO> IdTypesSearch;
protected SearchBuilder<VMInstanceVO> HostIdTypesSearch;
protected SearchBuilder<VMInstanceVO> HostIdStatesSearch;
protected SearchBuilder<VMInstanceVO> HostIdUpTypesSearch;
protected SearchBuilder<VMInstanceVO> HostUpSearch;
protected SearchBuilder<VMInstanceVO> InstanceNameSearch;
@ -180,6 +185,11 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
HostIdTypesSearch.and("types", HostIdTypesSearch.entity().getType(), Op.IN);
HostIdTypesSearch.done();
HostIdStatesSearch = createSearchBuilder();
HostIdStatesSearch.and("hostId", HostIdStatesSearch.entity().getHostId(), Op.EQ);
HostIdStatesSearch.and("states", HostIdStatesSearch.entity().getState(), Op.IN);
HostIdStatesSearch.done();
HostIdUpTypesSearch = createSearchBuilder();
HostIdUpTypesSearch.and("hostid", HostIdUpTypesSearch.entity().getHostId(), Op.EQ);
HostIdUpTypesSearch.and("types", HostIdUpTypesSearch.entity().getType(), Op.IN);
@ -230,7 +240,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
_updateTimeAttr = _allAttributes.get("updateTime");
assert _updateTimeAttr != null : "Couldn't get this updateTime attribute";
SearchBuilder<NicVO> nicSearch = _nicDao.createSearchBuilder();
nicSearch.and("networkId", nicSearch.entity().getNetworkId(), SearchCriteria.Op.EQ);
@ -242,7 +252,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
DistinctHostNameSearch.join("nicSearch", nicSearch, DistinctHostNameSearch.entity().getId(),
nicSearch.entity().getInstanceId(), JoinBuilder.JoinType.INNER);
DistinctHostNameSearch.done();
}
@Override
@ -334,6 +344,15 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
return listBy(sc);
}
@Override
public List<VMInstanceVO> listByHostAndState(long hostId, State... states) {
SearchCriteria<VMInstanceVO> sc = HostIdStatesSearch.create();
sc.setParameters("hostId", hostId);
sc.setParameters("states", (Object[])states);
return listBy(sc);
}
@Override
public List<VMInstanceVO> listUpByHostIdTypes(long hostid, Type... types) {
SearchCriteria<VMInstanceVO> sc = HostIdUpTypesSearch.create();
@ -679,63 +698,68 @@ public class VMInstanceDaoImpl extends GenericDaoBase<VMInstanceVO, Long> implem
sc.setParameters("state", State.Starting);
return listBy(sc);
}
@Override
public boolean updatePowerState(long instanceId, long powerHostId, VirtualMachine.PowerState powerState) {
boolean needToUpdate = false;
TransactionLegacy txn = TransactionLegacy.currentTxn();
txn.start();
VMInstanceVO instance = findById(instanceId);
if(instance != null) {
Long savedPowerHostId = instance.getPowerHostId();
if(instance.getPowerState() != powerState || savedPowerHostId == null
|| savedPowerHostId.longValue() != powerHostId) {
instance.setPowerState(powerState);
instance.setPowerHostId(powerHostId);
instance.setPowerStateUpdateCount(1);
instance.setPowerStateUpdateTime(DateUtil.currentGMTTime());
needToUpdate = true;
update(instanceId, instance);
} else {
// to reduce DB updates, consecutive same state update for more than 3 times
if(instance.getPowerStateUpdateCount() < MAX_CONSECUTIVE_SAME_STATE_UPDATE_COUNT) {
instance.setPowerStateUpdateCount(instance.getPowerStateUpdateCount() + 1);
instance.setPowerStateUpdateTime(DateUtil.currentGMTTime());
needToUpdate = true;
update(instanceId, instance);
}
}
}
txn.commit();
return needToUpdate;
public boolean updatePowerState(final long instanceId, final long powerHostId, final VirtualMachine.PowerState powerState) {
return Transaction.execute(new TransactionCallback<Boolean>() {
@Override
public Boolean doInTransaction(TransactionStatus status) {
boolean needToUpdate = false;
VMInstanceVO instance = findById(instanceId);
if(instance != null) {
Long savedPowerHostId = instance.getPowerHostId();
if(instance.getPowerState() != powerState || savedPowerHostId == null
|| savedPowerHostId.longValue() != powerHostId) {
instance.setPowerState(powerState);
instance.setPowerHostId(powerHostId);
instance.setPowerStateUpdateCount(1);
instance.setPowerStateUpdateTime(DateUtil.currentGMTTime());
needToUpdate = true;
update(instanceId, instance);
} else {
// to reduce DB updates, consecutive same state update for more than 3 times
if(instance.getPowerStateUpdateCount() < MAX_CONSECUTIVE_SAME_STATE_UPDATE_COUNT) {
instance.setPowerStateUpdateCount(instance.getPowerStateUpdateCount() + 1);
instance.setPowerStateUpdateTime(DateUtil.currentGMTTime());
needToUpdate = true;
update(instanceId, instance);
}
}
}
return needToUpdate;
}
});
}
@Override
public void resetVmPowerStateTracking(long instanceId) {
TransactionLegacy txn = TransactionLegacy.currentTxn();
txn.start();
VMInstanceVO instance = findById(instanceId);
if(instance != null) {
instance.setPowerStateUpdateCount(0);
instance.setPowerStateUpdateTime(DateUtil.currentGMTTime());
update(instanceId, instance);
}
txn.commit();
public void resetVmPowerStateTracking(final long instanceId) {
Transaction.execute(new TransactionCallbackNoReturn() {
@Override
public void doInTransactionWithoutResult(TransactionStatus status) {
VMInstanceVO instance = findById(instanceId);
if (instance != null) {
instance.setPowerStateUpdateCount(0);
instance.setPowerStateUpdateTime(DateUtil.currentGMTTime());
update(instanceId, instance);
}
}
});
}
@Override @DB
public void resetHostPowerStateTracking(long hostId) {
SearchCriteria<VMInstanceVO> sc = createSearchCriteria();
sc.addAnd("powerHostId", SearchCriteria.Op.EQ, hostId);
VMInstanceVO instance = this.createForUpdate();
instance.setPowerStateUpdateCount(0);
instance.setPowerStateUpdateTime(DateUtil.currentGMTTime());
this.update(instance, sc);
public void resetHostPowerStateTracking(final long hostId) {
Transaction.execute(new TransactionCallbackNoReturn() {
@Override
public void doInTransactionWithoutResult(TransactionStatus status) {
SearchCriteria<VMInstanceVO> sc = createSearchCriteria();
sc.addAnd("powerHostId", SearchCriteria.Op.EQ, hostId);
VMInstanceVO instance = createForUpdate();
instance.setPowerStateUpdateCount(0);
instance.setPowerStateUpdateTime(DateUtil.currentGMTTime());
update(instance, sc);
}
});
}
}

View File

@ -159,8 +159,9 @@ public class VolumeServiceImpl implements VolumeService {
return null;
}
@Override
public boolean connectVolumeToHost(VolumeInfo volumeInfo, Host host, DataStore dataStore) {
DataStoreDriver dataStoreDriver = dataStore.getDriver();
DataStoreDriver dataStoreDriver = dataStore != null ? dataStore.getDriver() : null;
if (dataStoreDriver instanceof PrimaryDataStoreDriver) {
return ((PrimaryDataStoreDriver)dataStoreDriver).connectVolumeToHost(volumeInfo, host, dataStore);
@ -169,8 +170,9 @@ public class VolumeServiceImpl implements VolumeService {
return false;
}
@Override
public void disconnectVolumeFromHost(VolumeInfo volumeInfo, Host host, DataStore dataStore) {
DataStoreDriver dataStoreDriver = dataStore.getDriver();
DataStoreDriver dataStoreDriver = dataStore != null ? dataStore.getDriver() : null;
if (dataStoreDriver instanceof PrimaryDataStoreDriver) {
((PrimaryDataStoreDriver)dataStoreDriver).disconnectVolumeFromHost(volumeInfo, host, dataStore);

View File

@ -20,25 +20,31 @@ package org.apache.cloudstack.framework.messagebus;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
public class MessageDispatcher implements MessageSubscriber {
private static Map<Class<?>, Method> s_handlerCache = new HashMap<Class<?>, Method>();
private static final Logger s_logger = Logger.getLogger(MessageDispatcher.class);
private static Map<Class<?>, List<Method>> s_handlerCache = new HashMap<Class<?>, List<Method>>();
private static Map<Object, MessageDispatcher> s_targetMap = new HashMap<Object, MessageDispatcher>();
private Object _targetObject;
public MessageDispatcher(Object targetObject) {
_targetObject = targetObject;
buildHandlerMethodCache(targetObject.getClass());
}
@Override
public void onPublishMessage(String senderAddress, String subject, Object args) {
dispatch(_targetObject, subject, senderAddress, args);
}
public static MessageDispatcher getDispatcher(Object targetObject) {
MessageDispatcher dispatcher;
synchronized(s_targetMap) {
@ -50,55 +56,94 @@ public class MessageDispatcher implements MessageSubscriber {
}
return dispatcher;
}
public static void removeDispatcher(Object targetObject) {
synchronized(s_targetMap) {
s_targetMap.remove(targetObject);
}
}
public static boolean dispatch(Object target, String subject, String senderAddress, Object args) {
assert(subject != null);
assert(target != null);
Method handler = resolveHandler(target.getClass(), subject);
if(handler == null)
return false;
try {
handler.invoke(target, subject, senderAddress, args);
} catch (IllegalArgumentException e) {
s_logger.error("Unexpected exception when calling " + target.getClass().getName() + "." + handler.getName(), e);
throw new RuntimeException("IllegalArgumentException when invoking event handler for subject: " + subject);
} catch (IllegalAccessException e) {
s_logger.error("Unexpected exception when calling " + target.getClass().getName() + "." + handler.getName(), e);
throw new RuntimeException("IllegalAccessException when invoking event handler for subject: " + subject);
} catch (InvocationTargetException e) {
s_logger.error("Unexpected exception when calling " + target.getClass().getName() + "." + handler.getName(), e);
throw new RuntimeException("InvocationTargetException when invoking event handler for subject: " + subject);
}
return true;
}
public static Method resolveHandler(Class<?> handlerClz, String subject) {
synchronized(s_handlerCache) {
Method handler = s_handlerCache.get(handlerClz);
if(handler != null)
return handler;
for(Method method : handlerClz.getMethods()) {
MessageHandler annotation = method.getAnnotation(MessageHandler.class);
if(annotation != null) {
if(match(annotation.topic(), subject)) {
s_handlerCache.put(handlerClz, method);
return method;
}
}
}
List<Method> handlerList = s_handlerCache.get(handlerClz);
if (handlerList != null) {
for (Method method : handlerList) {
MessageHandler annotation = method.getAnnotation(MessageHandler.class);
assert (annotation != null);
if (match(annotation.topic(), subject)) {
return method;
}
}
} else {
s_logger.error("Handler class " + handlerClz.getName() + " is not registered");
}
}
return null;
}
private static boolean match(String expression, String param) {
return param.matches(expression);
}
private void buildHandlerMethodCache(Class<?> handlerClz) {
if (s_logger.isInfoEnabled())
s_logger.info("Build message handler cache for " + handlerClz.getName());
synchronized (s_handlerCache) {
List<Method> handlerList = s_handlerCache.get(handlerClz);
if (handlerList == null) {
handlerList = new ArrayList<Method>();
s_handlerCache.put(handlerClz, handlerList);
Class<?> clz = handlerClz;
while (clz != null && clz != Object.class) {
for (Method method : clz.getDeclaredMethods()) {
MessageHandler annotation = method.getAnnotation(MessageHandler.class);
if (annotation != null) {
// allow private member access via reflection
method.setAccessible(true);
handlerList.add(method);
if (s_logger.isInfoEnabled())
s_logger.info("Add message handler " + handlerClz.getName() + "." + method.getName() + " to cache");
}
}
clz = clz.getSuperclass();
}
} else {
if (s_logger.isInfoEnabled())
s_logger.info("Message handler for class " + handlerClz.getName() + " is already in cache");
}
}
if (s_logger.isInfoEnabled())
s_logger.info("Done building message handler cache for " + handlerClz.getName());
}
}

View File

@ -61,7 +61,7 @@ namespace HypervResource
get
{
string uncPath = null;
if (uri.Scheme.Equals("cifs") || uri.Scheme.Equals("networkfilesystem"))
if (uri != null && (uri.Scheme.Equals("cifs") || uri.Scheme.Equals("networkfilesystem")))
{
uncPath = @"\\" + uri.Host + uri.LocalPath;
}
@ -73,8 +73,13 @@ namespace HypervResource
{
get
{
var queryDictionary = System.Web.HttpUtility.ParseQueryString(uri.Query);
return System.Web.HttpUtility.UrlDecode(queryDictionary["user"]);
string user = null;
if (uri != null)
{
var queryDictionary = System.Web.HttpUtility.ParseQueryString(uri.Query);
user = System.Web.HttpUtility.UrlDecode(queryDictionary["user"]);
}
return user;
}
}
@ -82,8 +87,13 @@ namespace HypervResource
{
get
{
var queryDictionary = System.Web.HttpUtility.ParseQueryString(uri.Query);
return System.Web.HttpUtility.UrlDecode(queryDictionary["password"]);
string password = null;
if (uri != null)
{
var queryDictionary = System.Web.HttpUtility.ParseQueryString(uri.Query);
password = System.Web.HttpUtility.UrlDecode(queryDictionary["password"]);
}
return password;
}
}
@ -91,12 +101,17 @@ namespace HypervResource
{
get
{
var queryDictionary = System.Web.HttpUtility.ParseQueryString(uri.Query);
if (queryDictionary["domain"] != null)
string domain = null;
if (uri != null)
{
return System.Web.HttpUtility.UrlDecode(queryDictionary["domain"]);
var queryDictionary = System.Web.HttpUtility.ParseQueryString(uri.Query);
if (queryDictionary["domain"] != null)
{
domain = System.Web.HttpUtility.UrlDecode(queryDictionary["domain"]);
}
else domain = uri.Host;
}
else return uri.Host;
return domain;
}
}

View File

@ -1474,15 +1474,8 @@ namespace HypervResource
{
// TODO: thin provision instead of copying the full file.
File.Copy(srcFile, destFile);
VolumeObjectTO volume = new VolumeObjectTO();
volume.path = destFile;
volume.dataStore = destVolumeObjectTO.dataStore;
volume.name = destVolumeObjectTO.name;
volume.size = ulong.Parse(destVolumeObjectTO.size.ToString());
volume.format = destVolumeObjectTO.format;
volume.nfsDataStore = destVolumeObjectTO.nfsDataStore;
volume.primaryDataStore = destVolumeObjectTO.primaryDataStore;
JObject ansObj = Utils.CreateCloudStackObject(CloudStackTypes.VolumeObjectTO, volume);
destVolumeObjectTO.path = destFile;
JObject ansObj = Utils.CreateCloudStackObject(CloudStackTypes.VolumeObjectTO, destVolumeObjectTO);
newData = ansObj;
result = true;
}

View File

@ -101,7 +101,11 @@ public class XenServerGuru extends HypervisorGuruBase implements HypervisorGuru
if (volume.getVolumeType() == Volume.Type.DATADISK) {
StoragePoolVO storagePool = _storagePoolDao.findById(volume.getPoolId());
if (storagePool.isManaged()) {
// storagePool should be null if we are expunging a volume that was never
// attached to a VM that was started (the "trick" for storagePool to be null
// is that none of the VMs this volume may have been attached to were ever started,
// so the volume was never assigned to a storage pool)
if (storagePool != null && storagePool.isManaged()) {
DataTO volTO = _volFactory.getVolume(volume.getId()).getTO();
DiskTO disk = new DiskTO(volTO, volume.getDeviceId(), volume.getPath(), volume.getVolumeType());

View File

@ -32,12 +32,17 @@ import com.cloud.agent.api.Command;
import com.cloud.agent.api.NetworkUsageAnswer;
import com.cloud.agent.api.NetworkUsageCommand;
import com.cloud.agent.api.StartupRoutingCommand;
import com.cloud.agent.api.StartupStorageCommand;
import com.cloud.agent.api.StopAnswer;
import com.cloud.agent.api.StopCommand;
import com.cloud.agent.api.StoragePoolInfo;
import com.cloud.resource.ServerResource;
import com.cloud.storage.Storage;
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.script.Script;
import com.xensource.xenapi.Connection;
import com.xensource.xenapi.Host;
import com.xensource.xenapi.SR;
import com.xensource.xenapi.Types;
import com.xensource.xenapi.Types.XenAPIException;
import com.xensource.xenapi.VBD;
@ -69,6 +74,38 @@ public class XcpOssResource extends CitrixResourceBase {
cmd.setCaps(cmd.getCapabilities() + " , hvm");
}
protected StartupStorageCommand initializeLocalSR(Connection conn) {
SR extsr = getLocalEXTSR(conn);
if (extsr != null) {
try {
String extuuid = extsr.getUuid(conn);
_host.localSRuuid = extuuid;
long cap = extsr.getPhysicalSize(conn);
if (cap > 0) {
long avail = cap - extsr.getPhysicalUtilisation(conn);
String name = "Cloud Stack Local EXT Storage Pool for " + _host.uuid;
extsr.setNameDescription(conn, name);
Host host = Host.getByUuid(conn, _host.uuid);
String address = host.getAddress(conn);
StoragePoolInfo pInfo = new StoragePoolInfo(extsr.getNameLabel(conn), address, SRType.EXT.toString(), SRType.EXT.toString(), Storage.StoragePoolType.EXT, cap, avail);
StartupStorageCommand cmd = new StartupStorageCommand();
cmd.setPoolInfo(pInfo);
cmd.setGuid(_host.uuid);
cmd.setDataCenter(Long.toString(_dcId));
cmd.setResourceType(Storage.StorageResourceType.STORAGE_POOL);
return cmd;
}
} catch (XenAPIException e) {
String msg = "build local EXT info err in host:" + _host.uuid + e.toString();
s_logger.warn(msg);
} catch (XmlRpcException e) {
String msg = "build local EXT info err in host:" + _host.uuid + e.getMessage();
s_logger.warn(msg);
}
}
return null;
}
@Override
protected String getGuestOsType(String stdType, boolean bootFromCD) {
if (stdType.equalsIgnoreCase("Debian GNU/Linux 6(64-bit)")) {

View File

@ -78,6 +78,7 @@ public class ContrailElementImpl extends AdapterBase
private static final Map<Service, Map<Capability, String>> _capabilities = InitCapabilities();
@Inject ResourceManager _resourceMgr;
@Inject ConfigurationServer _configServer;
@Inject NetworkDao _networksDao;
@Inject ContrailManager _manager;
@Inject NicDao _nicDao;
@ -284,6 +285,32 @@ public class ContrailElementImpl extends AdapterBase
@Override
public boolean isReady(PhysicalNetworkServiceProvider provider) {
Map<String, String> serviceMap = ((ConfigurationServerImpl)_configServer).getServicesAndProvidersForNetwork( _manager.getRouterOffering().getId());
List<TrafficType> types = new ArrayList<TrafficType>();
types.add(TrafficType.Control);
types.add(TrafficType.Management);
types.add(TrafficType.Storage);
List<NetworkVO> systemNets = _manager.findSystemNetworks(types);
if (systemNets != null && !systemNets.isEmpty()) {
for (NetworkVO net: systemNets) {
s_logger.debug("update system network service: " + net.getName() + "; service provider: " + serviceMap);
_networksDao.update(net.getId(), net, serviceMap);
}
} else {
s_logger.debug("no system networks created yet");
}
serviceMap = ((ConfigurationServerImpl)_configServer).getServicesAndProvidersForNetwork( _manager.getPublicRouterOffering().getId());
types = new ArrayList<TrafficType>();
types.add(TrafficType.Public);
systemNets = _manager.findSystemNetworks(types);
if (systemNets != null && !systemNets.isEmpty()) {
for (NetworkVO net: systemNets) {
s_logger.debug("update system network service: " + net.getName() + "; service provider: " + serviceMap);
_networksDao.update(net.getId(), net, serviceMap);
}
} else {
s_logger.debug("no system networks created yet");
}
return true;
}

View File

@ -40,6 +40,9 @@ import com.cloud.deploy.DeploymentPlan;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientAddressCapacityException;
import com.cloud.exception.InsufficientVirtualNetworkCapcityException;
import com.cloud.dc.DataCenter;
import com.cloud.dc.DataCenter.NetworkType;
import com.cloud.dc.dao.DataCenterDao;
import com.cloud.network.Network;
import com.cloud.network.Network.State;
import com.cloud.network.NetworkProfile;
@ -50,6 +53,10 @@ import com.cloud.network.Networks.TrafficType;
import com.cloud.network.dao.NetworkDao;
import com.cloud.network.dao.NetworkVO;
import com.cloud.network.guru.NetworkGuru;
import com.cloud.network.PhysicalNetwork;
import com.cloud.network.PhysicalNetwork.IsolationMethod;
import com.cloud.network.dao.PhysicalNetworkDao;
import com.cloud.network.dao.PhysicalNetworkVO;
import com.cloud.offering.NetworkOffering;
import com.cloud.user.Account;
import com.cloud.utils.component.AdapterBase;
@ -74,6 +81,8 @@ public class ContrailGuru extends AdapterBase implements NetworkGuru {
@Inject NetworkDao _networkDao;
@Inject ContrailManager _manager;
@Inject NicDao _nicDao;
@Inject PhysicalNetworkDao _physicalNetworkDao;
@Inject DataCenterDao _dcDao;
@Inject IPAddressDao _ipAddressDao;
@Inject AccountManager _accountMgr;
@Inject IpAddressManager _ipAddrMgr;
@ -81,12 +90,16 @@ public class ContrailGuru extends AdapterBase implements NetworkGuru {
private static final Logger s_logger = Logger.getLogger(ContrailGuru.class);
private static final TrafficType[] _trafficTypes = {TrafficType.Guest};
private boolean canHandle(NetworkOffering offering) {
if (offering.getId() == _manager.getRouterOffering().getId())
private boolean canHandle(NetworkOffering offering, NetworkType networkType, PhysicalNetwork physicalNetwork) {
if (networkType == NetworkType.Advanced
&& isMyTrafficType(offering.getTrafficType())
&& offering.getGuestType() == Network.GuestType.Isolated
&& physicalNetwork.getIsolationMethods().contains("L3VPN"))
return true;
return false;
}
return false;
}
@Override
public String getName() {
return "ContrailGuru";
@ -95,7 +108,11 @@ public class ContrailGuru extends AdapterBase implements NetworkGuru {
@Override
public Network design(NetworkOffering offering, DeploymentPlan plan,
Network userSpecified, Account owner) {
if (!canHandle(offering)) {
// Check of the isolation type of the related physical network is L3VPN
PhysicalNetworkVO physnet = _physicalNetworkDao.findById(plan.getPhysicalNetworkId());
DataCenter dc = _dcDao.findById(plan.getDataCenterId());
if (!canHandle(offering, dc.getNetworkType(),physnet)) {
s_logger.debug("Refusing to design this network");
return null;
}
NetworkVO network = new NetworkVO(offering.getTrafficType(), Mode.Dhcp, BroadcastDomainType.Lswitch,

View File

@ -54,7 +54,7 @@ public interface ContrailManager {
public NetworkOffering getRouterOffering();
public NetworkOffering getPublicRouterOffering();
public void syncNetworkDB(short syncMode) throws IOException;
public void syncNetworkDB(short syncMode) throws Exception;
public boolean isManagedPhysicalNetwork(Network network);

View File

@ -30,6 +30,7 @@ import java.util.TimerTask;
import javax.inject.Inject;
import javax.naming.ConfigurationException;
import javax.ejb.Local;
import net.juniper.contrail.api.ApiConnector;
import net.juniper.contrail.api.ApiConnectorFactory;
@ -99,7 +100,7 @@ import com.cloud.vm.dao.VMInstanceDao;
import java.io.File;
import java.io.FileInputStream;
@Component
@Local(value = { ContrailManager.class})
public class ContrailManagerImpl extends ManagerBase implements ContrailManager {
@Inject public ConfigurationService _configService;
@Inject ConfigurationServer _configServer;
@ -135,7 +136,6 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager
private ModelController _controller;
ContrailManagerImpl() {
setRunLevel(ComponentLifecycle.RUN_LEVEL_COMPONENT);
_database = new ModelDatabase();
}
@ -242,24 +242,33 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager
public boolean configure(String name, Map<String, Object> params) throws ConfigurationException {
File configFile = PropertiesUtil.findConfigFile(configuration);
final Properties configProps = new Properties();
try {
configProps.load(new FileInputStream(configFile));
String value = configProps.getProperty("management.db_sync_interval");
if (value != null) {
_dbSyncInterval = Integer.valueOf(value);
}
String hostname = configProps.getProperty("api.hostname");
String portStr = configProps.getProperty("api.port");
String hostname = null;
int port = 0;
if (portStr != null && portStr.length() > 0) {
port = Integer.parseInt(portStr);
if (configFile == null) {
hostname = "localhost";
port = 8082;
} else {
final Properties configProps = new Properties();
configProps.load(new FileInputStream(configFile));
String value = configProps.getProperty("management.db_sync_interval");
if (value != null) {
_dbSyncInterval = Integer.valueOf(value);
}
hostname = configProps.getProperty("api.hostname");
String portStr = configProps.getProperty("api.port");
if (portStr != null && portStr.length() > 0) {
port = Integer.parseInt(portStr);
}
}
_api = ApiConnectorFactory.build(hostname, port);
} catch (IOException ex) {
s_logger.warn("Unable to read " + configuration, ex);
throw new ConfigurationException();
} catch (Exception ex) {
s_logger.debug("Exception in configure: " + ex);
ex.printStackTrace();
throw new ConfigurationException();
}
_controller = new ModelController(this, _api, _vmDao, _networksDao, _nicDao, _vlanDao, _ipAddressDao);
@ -416,7 +425,7 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager
}
public void syncNetworkDB(short syncMode) throws IOException {
public void syncNetworkDB(short syncMode) throws Exception {
if (_dbSync.syncAll(syncMode) == ServerDBSync.SYNC_STATE_OUT_OF_SYNC) {
if (syncMode == DBSyncGeneric.SYNC_MODE_CHECK) {
s_logger.info("# Cloudstack DB & VNC are out of sync #");
@ -440,6 +449,7 @@ public class ContrailManagerImpl extends ManagerBase implements ContrailManager
} catch (Exception ex) {
s_logger.debug(ex);
s_logger.info("Unable to sync network db");
//resync will be done after _dbSyncInterval seconds since _syncMode is still set to SYNC_MODE_UPDATE
}
}
}

View File

@ -32,7 +32,7 @@ public interface ServerDBSync {
* API for syncing all classes of vnc objects with cloudstack
* Sync cloudstack and vnc objects.
*/
public short syncAll(short syncMode);
public short syncAll(short syncMode) throws Exception;
public void syncClass(Class<?> cls);
public void createProject(ProjectVO project, StringBuffer syncLogMesg) throws IOException;
public void createDomain(DomainVO domain, StringBuffer logMesg)throws IOException;

View File

@ -117,7 +117,7 @@ public class ServerDBSyncImpl implements ServerDBSync {
* Order has to be maintained
*/
@Override
public short syncAll(short syncMode) {
public short syncAll(short syncMode) throws Exception {
short syncState = SYNC_STATE_IN_SYNC;
/* vnc classes need to be synchronized with cloudstack */
@ -158,6 +158,7 @@ public class ServerDBSyncImpl implements ServerDBSync {
if (_lockSyncMode.isLocked()) {
_lockSyncMode.unlock();
}
throw ex;
}
return syncState;

View File

@ -120,7 +120,7 @@ public class NetworkPolicyModel extends ModelObjectBase {
}
Integer portStart = rule.getSourcePortStart();
Integer portEnd = rule.getSourcePortStart();
Integer portEnd = rule.getSourcePortEnd();
if (portStart == null) {
portStart = 0;
}

View File

@ -319,7 +319,7 @@ public class ManagementServerMock {
}
} catch (InvalidParameterValueException e) {
List<String> isolationMethods = new ArrayList<String>();
isolationMethods.add("GRE");
isolationMethods.add("L3VPN");
_znet = _networkService.createPhysicalNetwork(_zone.getId(), null, null, isolationMethods,
BroadcastDomainRange.ZONE.toString(), _zone.getDomainId(),
null, "znet");

View File

@ -462,15 +462,19 @@ public class NetworkProviderTest extends TestCase {
} catch (IOException ex) {
fail(ex.getMessage());
}
//now db sync
if (_dbSync.syncAll(DBSyncGeneric.SYNC_MODE_UPDATE) == ServerDBSync.SYNC_STATE_OUT_OF_SYNC) {
s_logger.info("# Cloudstack DB & VNC are out of sync - resync done");
}
if (_dbSync.syncAll(DBSyncGeneric.SYNC_MODE_CHECK) == ServerDBSync.SYNC_STATE_OUT_OF_SYNC) {
s_logger.info("# Cloudstack DB & VNC are still out of sync");
fail("DB Sync failed");
try {
if (_dbSync.syncAll(DBSyncGeneric.SYNC_MODE_UPDATE) == ServerDBSync.SYNC_STATE_OUT_OF_SYNC) {
s_logger.info("# Cloudstack DB & VNC are out of sync - resync done");
}
if (_dbSync.syncAll(DBSyncGeneric.SYNC_MODE_CHECK) == ServerDBSync.SYNC_STATE_OUT_OF_SYNC) {
s_logger.info("# Cloudstack DB & VNC are still out of sync");
fail("DB Sync failed");
}
} catch (Exception ex) {
fail(ex.getMessage());
}
}

View File

@ -1489,12 +1489,13 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
}
}
DataStore dataStore = dataStoreMgr.getDataStore(volume.getPoolId(), DataStoreRole.Primary);
if (!sendCommand || (answer != null && answer.getResult())) {
// Mark the volume as detached
_volsDao.detachVolume(volume.getId());
// volume.getPoolId() should be null if the VM we are attaching the disk to has never been started before
DataStore dataStore = volume.getPoolId() != null ? dataStoreMgr.getDataStore(volume.getPoolId(), DataStoreRole.Primary) : null;
volService.disconnectVolumeFromHost(volFactory.getVolume(volume.getId()), host, dataStore);
return _volsDao.findById(volumeId);
@ -1961,10 +1962,12 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
}
}
DataStore dataStore = dataStoreMgr.getDataStore(volumeToAttachStoragePool.getId(), DataStoreRole.Primary);
// volumeToAttachStoragePool should be null if the VM we are attaching the disk to has never been started before
DataStore dataStore = volumeToAttachStoragePool != null ? dataStoreMgr.getDataStore(volumeToAttachStoragePool.getId(), DataStoreRole.Primary) : null;
boolean queryForChap = true;
// if we don't have a host, the VM we are attaching the disk to has never been started before
if (host != null) {
try {
// if connectVolumeToHost returns true, then we do not want to use CHAP because the volume is already connected to the host(s)

View File

@ -20,6 +20,7 @@ set -x
ROOTPW=password
HOSTNAME=systemvm
CLOUDSTACK_RELEASE=4.3.0
ARCH=64-bit
add_backports () {
sed -i '/backports/d' /etc/apt/sources.list
@ -246,7 +247,7 @@ do_signature() {
mkdir -p /var/cache/cloud/
gzip -c /usr/share/cloud/cloud-scripts.tar > /usr/share/cloud/cloud-scripts.tgz
md5sum /usr/share/cloud/cloud-scripts.tgz | awk '{print $1}' > /var/cache/cloud/cloud-scripts-signature
echo "Cloudstack Release $CLOUDSTACK_RELEASE $(date)" > /etc/cloudstack-release
echo "Cloudstack Release $CLOUDSTACK_RELEASE ($ARCH) $(date)" > /etc/cloudstack-release
}
begin=$(date +%s)

View File

@ -19,7 +19,8 @@ set -x
ROOTPW=password
HOSTNAME=systemvm
CLOUDSTACK_RELEASE=4.2.0
CLOUDSTACK_RELEASE=4.3.0
ARCH=32-bit
add_backports () {
sed -i '/backports/d' /etc/apt/sources.list
@ -227,7 +228,7 @@ do_signature() {
mkdir -p /var/cache/cloud/
gzip -c /usr/share/cloud/cloud-scripts.tar > /usr/share/cloud/cloud-scripts.tgz
md5sum /usr/share/cloud/cloud-scripts.tgz | awk '{print $1}' > /var/cache/cloud/cloud-scripts-signature
echo "Cloudstack Release $CLOUDSTACK_RELEASE $(date)" > /etc/cloudstack-release
echo "Cloudstack Release $CLOUDSTACK_RELEASE ($ARCH) $(date)" > /etc/cloudstack-release
}
begin=$(date +%s)

View File

@ -2222,7 +2222,11 @@
}
}
if (ipAddress.vpcid || ipAddress.issourcenat) {
if (ipAddress.issourcenat) {
disableIpRules = true;
}
if (('vpc' in args.context) == false && ipAddress.vpcid != null) { //from Guest Network section, don't show Configuration(ipRules) tab on VPC IP
disableIpRules = true;
}

View File

@ -720,7 +720,10 @@
}).html('SSP'),
$('<option>').attr({
value: 'VXLAN'
}).html('VXLAN')
}).html('VXLAN'),
$('<option>').attr({
value: 'L3VPN'
}).html('L3VPN')
)
)
);