diff --git a/api/src/com/cloud/network/PhysicalNetwork.java b/api/src/com/cloud/network/PhysicalNetwork.java index 55b18e67ba9..5d38b500305 100644 --- a/api/src/com/cloud/network/PhysicalNetwork.java +++ b/api/src/com/cloud/network/PhysicalNetwork.java @@ -40,7 +40,8 @@ public interface PhysicalNetwork extends Identity, InternalIdentity { VNS, MIDO, SSP, - VXLAN; + VXLAN, + L3VPN; } public enum BroadcastDomainRange { diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java index 17f0936ab46..af65ac6d2cb 100755 --- a/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java +++ b/engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java @@ -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; diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachinePowerStateSync.java b/engine/orchestration/src/com/cloud/vm/VirtualMachinePowerStateSync.java index dacc8d09067..d7aef72aea2 100644 --- a/engine/orchestration/src/com/cloud/vm/VirtualMachinePowerStateSync.java +++ b/engine/orchestration/src/com/cloud/vm/VirtualMachinePowerStateSync.java @@ -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 report); - + // to adapt legacy ping report void processHostVmStatePingReport(long hostId, Map report); + + Map convertVmStateReport(Map states); } diff --git a/engine/orchestration/src/com/cloud/vm/VirtualMachinePowerStateSyncImpl.java b/engine/orchestration/src/com/cloud/vm/VirtualMachinePowerStateSyncImpl.java index 9aa95013b08..9a0119ca41f 100644 --- a/engine/orchestration/src/com/cloud/vm/VirtualMachinePowerStateSyncImpl.java +++ b/engine/orchestration/src/com/cloud/vm/VirtualMachinePowerStateSyncImpl.java @@ -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 report) { if(s_logger.isDebugEnabled()) s_logger.debug("Process host VM state report from ping process. host: " + hostId); - - Map translatedInfo = convertToInfos(report); + + Map translatedInfo = convertVmStateReport(report); processReport(hostId, translatedInfo); } @@ -58,39 +58,41 @@ public class VirtualMachinePowerStateSyncImpl implements VirtualMachinePowerStat public void processHostVmStatePingReport(long hostId, Map report) { if(s_logger.isDebugEnabled()) s_logger.debug("Process host VM state report from ping process. host: " + hostId); - - Map translatedInfo = convertToInfos(report); + + Map translatedInfo = convertVmStateReport(report); processReport(hostId, translatedInfo); } - + private void processReport(long hostId, Map translatedInfo) { - + for(Map.Entry 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 convertToInfos(Map states) { + + @Override + public Map convertVmStateReport(Map states) { final HashMap map = new HashMap(); if (states == null) { return map; } - + for (Map.Entry 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); } diff --git a/engine/schema/src/com/cloud/upgrade/dao/Upgrade421to430.java b/engine/schema/src/com/cloud/upgrade/dao/Upgrade421to430.java index 268a27d2582..bf08e877ced 100644 --- a/engine/schema/src/com/cloud/upgrade/dao/Upgrade421to430.java +++ b/engine/schema/src/com/cloud/upgrade/dao/Upgrade421to430.java @@ -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) { diff --git a/engine/schema/src/com/cloud/vm/dao/VMInstanceDao.java b/engine/schema/src/com/cloud/vm/dao/VMInstanceDao.java index 830dea8aac7..78c6e8c9f61 100644 --- a/engine/schema/src/com/cloud/vm/dao/VMInstanceDao.java +++ b/engine/schema/src/com/cloud/vm/dao/VMInstanceDao.java @@ -70,6 +70,8 @@ public interface VMInstanceDao extends GenericDao, StateDao< List findVMInTransition(Date time, State... states); + List listByHostAndState(long hostId, State... states); + List listByTypes(VirtualMachine.Type... types); VMInstanceVO findByIdTypes(long id, VirtualMachine.Type... types); @@ -123,8 +125,8 @@ public interface VMInstanceDao extends GenericDao, StateDao< List listStartingWithNoHostId(); boolean updatePowerState(long instanceId, long powerHostId, VirtualMachine.PowerState powerState); - + void resetVmPowerStateTracking(long instanceId); - + void resetHostPowerStateTracking(long hostId); } diff --git a/engine/schema/src/com/cloud/vm/dao/VMInstanceDaoImpl.java b/engine/schema/src/com/cloud/vm/dao/VMInstanceDaoImpl.java index e7f907e6545..cc747bc5611 100644 --- a/engine/schema/src/com/cloud/vm/dao/VMInstanceDaoImpl.java +++ b/engine/schema/src/com/cloud/vm/dao/VMInstanceDaoImpl.java @@ -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 implem public static final Logger s_logger = Logger.getLogger(VMInstanceDaoImpl.class); private static final int MAX_CONSECUTIVE_SAME_STATE_UPDATE_COUNT = 3; - + protected SearchBuilder VMClusterSearch; protected SearchBuilder LHVMClusterSearch; protected SearchBuilder IdStatesSearch; @@ -77,6 +81,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase implem protected SearchBuilder TypesSearch; protected SearchBuilder IdTypesSearch; protected SearchBuilder HostIdTypesSearch; + protected SearchBuilder HostIdStatesSearch; protected SearchBuilder HostIdUpTypesSearch; protected SearchBuilder HostUpSearch; protected SearchBuilder InstanceNameSearch; @@ -180,6 +185,11 @@ public class VMInstanceDaoImpl extends GenericDaoBase 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 implem _updateTimeAttr = _allAttributes.get("updateTime"); assert _updateTimeAttr != null : "Couldn't get this updateTime attribute"; - + SearchBuilder nicSearch = _nicDao.createSearchBuilder(); nicSearch.and("networkId", nicSearch.entity().getNetworkId(), SearchCriteria.Op.EQ); @@ -242,7 +252,7 @@ public class VMInstanceDaoImpl extends GenericDaoBase 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 implem return listBy(sc); } + @Override + public List listByHostAndState(long hostId, State... states) { + SearchCriteria sc = HostIdStatesSearch.create(); + sc.setParameters("hostId", hostId); + sc.setParameters("states", (Object[])states); + + return listBy(sc); + } + @Override public List listUpByHostIdTypes(long hostid, Type... types) { SearchCriteria sc = HostIdUpTypesSearch.create(); @@ -679,63 +698,68 @@ public class VMInstanceDaoImpl extends GenericDaoBase 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() { + @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 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 sc = createSearchCriteria(); + sc.addAnd("powerHostId", SearchCriteria.Op.EQ, hostId); + + VMInstanceVO instance = createForUpdate(); + instance.setPowerStateUpdateCount(0); + instance.setPowerStateUpdateTime(DateUtil.currentGMTTime()); + + update(instance, sc); + } + }); } } diff --git a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java index b9dbd92a875..7796565dadd 100644 --- a/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java +++ b/engine/storage/volume/src/org/apache/cloudstack/storage/volume/VolumeServiceImpl.java @@ -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); diff --git a/framework/ipc/src/org/apache/cloudstack/framework/messagebus/MessageDispatcher.java b/framework/ipc/src/org/apache/cloudstack/framework/messagebus/MessageDispatcher.java index ac75afb7c7d..e83c5ee7685 100644 --- a/framework/ipc/src/org/apache/cloudstack/framework/messagebus/MessageDispatcher.java +++ b/framework/ipc/src/org/apache/cloudstack/framework/messagebus/MessageDispatcher.java @@ -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, Method> s_handlerCache = new HashMap, Method>(); - + private static final Logger s_logger = Logger.getLogger(MessageDispatcher.class); + + private static Map, List> s_handlerCache = new HashMap, List>(); + private static Map s_targetMap = new HashMap(); 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 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 handlerList = s_handlerCache.get(handlerClz); + if (handlerList == null) { + handlerList = new ArrayList(); + 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()); + } } diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs index 89f0814214e..847380cb115 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/CloudStackTypes.cs @@ -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; } } diff --git a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs index 5ed3904398c..62eebdae982 100644 --- a/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs +++ b/plugins/hypervisors/hyperv/DotNet/ServerResource/HypervResource/HypervResourceController.cs @@ -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; } diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/XenServerGuru.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/XenServerGuru.java index af37068203f..28bd724ed4e 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/XenServerGuru.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/XenServerGuru.java @@ -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()); diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XcpOssResource.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XcpOssResource.java index fd222b77220..5260c55bcc2 100644 --- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XcpOssResource.java +++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/XcpOssResource.java @@ -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)")) { diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailElementImpl.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailElementImpl.java index 18e8bde221c..896ae8c6935 100644 --- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailElementImpl.java +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailElementImpl.java @@ -78,6 +78,7 @@ public class ContrailElementImpl extends AdapterBase private static final Map> _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 serviceMap = ((ConfigurationServerImpl)_configServer).getServicesAndProvidersForNetwork( _manager.getRouterOffering().getId()); + List types = new ArrayList(); + types.add(TrafficType.Control); + types.add(TrafficType.Management); + types.add(TrafficType.Storage); + List 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(); + 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; } diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailGuru.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailGuru.java index 6587534994e..4e8083b6cd2 100644 --- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailGuru.java +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailGuru.java @@ -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, diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManager.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManager.java index 550abb7c0e4..6489da9d042 100644 --- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManager.java +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManager.java @@ -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); diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java index eea5026a977..466e0434597 100644 --- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ContrailManagerImpl.java @@ -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 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 } } } diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerDBSync.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerDBSync.java index fea9a951e68..68319774c9f 100644 --- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerDBSync.java +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerDBSync.java @@ -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; diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerDBSyncImpl.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerDBSyncImpl.java index f8a8d978862..22c726abc85 100644 --- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerDBSyncImpl.java +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/management/ServerDBSyncImpl.java @@ -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; diff --git a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/NetworkPolicyModel.java b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/NetworkPolicyModel.java index d5a8722086a..aefc36bbeaf 100644 --- a/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/NetworkPolicyModel.java +++ b/plugins/network-elements/juniper-contrail/src/org/apache/cloudstack/network/contrail/model/NetworkPolicyModel.java @@ -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; } diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java index bbff4668119..36b5374187f 100644 --- a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java +++ b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/ManagementServerMock.java @@ -319,7 +319,7 @@ public class ManagementServerMock { } } catch (InvalidParameterValueException e) { List isolationMethods = new ArrayList(); - isolationMethods.add("GRE"); + isolationMethods.add("L3VPN"); _znet = _networkService.createPhysicalNetwork(_zone.getId(), null, null, isolationMethods, BroadcastDomainRange.ZONE.toString(), _zone.getDomainId(), null, "znet"); diff --git a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/NetworkProviderTest.java b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/NetworkProviderTest.java index 930ac4d6c15..89294cca078 100644 --- a/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/NetworkProviderTest.java +++ b/plugins/network-elements/juniper-contrail/test/org/apache/cloudstack/network/contrail/management/NetworkProviderTest.java @@ -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()); } } diff --git a/server/src/com/cloud/storage/VolumeApiServiceImpl.java b/server/src/com/cloud/storage/VolumeApiServiceImpl.java index 3de27675263..0c8954125ae 100644 --- a/server/src/com/cloud/storage/VolumeApiServiceImpl.java +++ b/server/src/com/cloud/storage/VolumeApiServiceImpl.java @@ -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) diff --git a/tools/appliance/definitions/systemvm64template/postinstall.sh b/tools/appliance/definitions/systemvm64template/postinstall.sh index d0c450d62bc..8a281f6b048 100644 --- a/tools/appliance/definitions/systemvm64template/postinstall.sh +++ b/tools/appliance/definitions/systemvm64template/postinstall.sh @@ -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) diff --git a/tools/appliance/definitions/systemvmtemplate/postinstall.sh b/tools/appliance/definitions/systemvmtemplate/postinstall.sh index 1309d47a9f5..822cd5f517a 100644 --- a/tools/appliance/definitions/systemvmtemplate/postinstall.sh +++ b/tools/appliance/definitions/systemvmtemplate/postinstall.sh @@ -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) diff --git a/ui/scripts/network.js b/ui/scripts/network.js index 610b1bdc2dc..c404b55b9b7 100755 --- a/ui/scripts/network.js +++ b/ui/scripts/network.js @@ -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; } diff --git a/ui/scripts/ui-custom/zoneWizard.js b/ui/scripts/ui-custom/zoneWizard.js index 28df1933fb2..7b3a8e1234f 100644 --- a/ui/scripts/ui-custom/zoneWizard.js +++ b/ui/scripts/ui-custom/zoneWizard.js @@ -720,7 +720,10 @@ }).html('SSP'), $('