mirror of https://github.com/apache/cloudstack.git
Merge branch 'master' into resize-root
This commit is contained in:
commit
6d6e790d81
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
# set environment variables
|
||||
|
||||
SHORTNAME="$0"
|
||||
SHORTNAME="basename $0"
|
||||
PIDFILE=@PIDDIR@/"$SHORTNAME".pid
|
||||
LOCKFILE=@LOCKDIR@/"$SHORTNAME"
|
||||
LOGFILE=@AGENTLOG@
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
# set environment variables
|
||||
|
||||
SHORTNAME="$0"
|
||||
SHORTNAME="basename $0"
|
||||
PIDFILE=@PIDDIR@/"$SHORTNAME".pid
|
||||
LOCKFILE=@LOCKDIR@/"$SHORTNAME"
|
||||
LOGFILE=@AGENTLOG@
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
# set environment variables
|
||||
|
||||
SHORTNAME="$0"
|
||||
SHORTNAME="basename $0"
|
||||
PIDFILE=@PIDDIR@/"$SHORTNAME".pid
|
||||
LOCKFILE=@LOCKDIR@/"$SHORTNAME"
|
||||
LOGFILE=@AGENTLOG@
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
# set environment variables
|
||||
|
||||
SHORTNAME="$0"
|
||||
SHORTNAME="basename $0"
|
||||
PIDFILE=@PIDDIR@/"$SHORTNAME".pid
|
||||
LOCKFILE=@LOCKDIR@/"$SHORTNAME"
|
||||
LOGFILE=@AGENTLOG@
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
# set environment variables
|
||||
|
||||
SHORTNAME="$0"
|
||||
SHORTNAME="basename $0"
|
||||
PIDFILE=@PIDDIR@/"$SHORTNAME".pid
|
||||
LOCKFILE=@LOCKDIR@/"$SHORTNAME"
|
||||
LOGFILE=@AGENTLOG@
|
||||
|
|
|
|||
|
|
@ -493,10 +493,13 @@ public class EventTypes {
|
|||
entityEventDetails.put(EVENT_VM_REBOOT, VirtualMachine.class.getName());
|
||||
entityEventDetails.put(EVENT_VM_UPDATE, VirtualMachine.class.getName());
|
||||
entityEventDetails.put(EVENT_VM_UPGRADE, VirtualMachine.class.getName());
|
||||
entityEventDetails.put(EVENT_VM_DYNAMIC_SCALE, VirtualMachine.class.getName());
|
||||
entityEventDetails.put(EVENT_VM_RESETPASSWORD, VirtualMachine.class.getName());
|
||||
entityEventDetails.put(EVENT_VM_RESETSSHKEY, VirtualMachine.class.getName());
|
||||
entityEventDetails.put(EVENT_VM_MIGRATE, VirtualMachine.class.getName());
|
||||
entityEventDetails.put(EVENT_VM_MOVE, VirtualMachine.class.getName());
|
||||
entityEventDetails.put(EVENT_VM_RESTORE, VirtualMachine.class.getName());
|
||||
entityEventDetails.put(EVENT_VM_EXPUNGE, VirtualMachine.class.getName());
|
||||
|
||||
entityEventDetails.put(EVENT_ROUTER_CREATE, VirtualRouter.class.getName());
|
||||
entityEventDetails.put(EVENT_ROUTER_DESTROY, VirtualRouter.class.getName());
|
||||
|
|
@ -544,9 +547,11 @@ public class EventTypes {
|
|||
entityEventDetails.put(EVENT_LB_CERT_REMOVE, LoadBalancer.class.getName());
|
||||
|
||||
// Account events
|
||||
entityEventDetails.put(EVENT_ACCOUNT_ENABLE, Account.class.getName());
|
||||
entityEventDetails.put(EVENT_ACCOUNT_DISABLE, Account.class.getName());
|
||||
entityEventDetails.put(EVENT_ACCOUNT_CREATE, Account.class.getName());
|
||||
entityEventDetails.put(EVENT_ACCOUNT_DELETE, Account.class.getName());
|
||||
entityEventDetails.put(EVENT_ACCOUNT_UPDATE, Account.class.getName());
|
||||
entityEventDetails.put(EVENT_ACCOUNT_MARK_DEFAULT_ZONE, Account.class.getName());
|
||||
|
||||
// UserVO Events
|
||||
|
|
|
|||
|
|
@ -16,10 +16,13 @@
|
|||
// under the License.
|
||||
package com.cloud.network;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
import com.cloud.exception.InsufficientCapacityException;
|
||||
import com.cloud.exception.ResourceUnavailableException;
|
||||
import com.cloud.network.router.VirtualRouter;
|
||||
import com.cloud.vm.VirtualMachineProfile;
|
||||
|
||||
public interface VpcVirtualNetworkApplianceService extends VirtualNetworkApplianceService {
|
||||
|
||||
|
|
@ -27,13 +30,14 @@ public interface VpcVirtualNetworkApplianceService extends VirtualNetworkApplian
|
|||
* @param router
|
||||
* @param network
|
||||
* @param isRedundant
|
||||
* @param params TODO
|
||||
* @return
|
||||
* @throws ConcurrentOperationException
|
||||
* @throws ResourceUnavailableException
|
||||
* @throws InsufficientCapacityException
|
||||
*/
|
||||
boolean addVpcRouterToGuestNetwork(VirtualRouter router, Network network, boolean isRedundant) throws ConcurrentOperationException, ResourceUnavailableException,
|
||||
InsufficientCapacityException;
|
||||
boolean addVpcRouterToGuestNetwork(VirtualRouter router, Network network, boolean isRedundant, Map<VirtualMachineProfile.Param, Object> params)
|
||||
throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException;
|
||||
|
||||
/**
|
||||
* @param router
|
||||
|
|
|
|||
|
|
@ -32,16 +32,17 @@ public class ConsoleProxyInfo {
|
|||
this.sslEnabled = sslEnabled;
|
||||
|
||||
if (sslEnabled) {
|
||||
StringBuffer sb = new StringBuffer(proxyIpAddress);
|
||||
for (int i = 0; i < sb.length(); i++)
|
||||
if (sb.charAt(i) == '.')
|
||||
sb.setCharAt(i, '-');
|
||||
if (consoleProxyUrlDomain != null && consoleProxyUrlDomain.length() > 0) {
|
||||
sb.append(".");
|
||||
StringBuffer sb = new StringBuffer();
|
||||
if (consoleProxyUrlDomain.startsWith("*")) {
|
||||
sb.append(proxyIpAddress);
|
||||
for (int i = 0; i < proxyIpAddress.length(); i++)
|
||||
if (sb.charAt(i) == '.')
|
||||
sb.setCharAt(i, '-');
|
||||
sb.append(consoleProxyUrlDomain.substring(1));//skip the *
|
||||
} else {
|
||||
//LB address
|
||||
sb.append(consoleProxyUrlDomain);
|
||||
} else
|
||||
sb.append(".realhostip.com");
|
||||
|
||||
}
|
||||
proxyAddress = sb.toString();
|
||||
proxyPort = port;
|
||||
this.proxyUrlPort = proxyUrlPort;
|
||||
|
|
|
|||
|
|
@ -188,7 +188,7 @@ public class CloudOrchestrator implements OrchestrationService {
|
|||
rootDiskOfferingInfo.setDiskOffering(offering);
|
||||
rootDiskOfferingInfo.setSize(rootDiskSize);
|
||||
|
||||
if (offering.isCustomizedIops()) {
|
||||
if (offering.isCustomizedIops() != null && offering.isCustomizedIops()) {
|
||||
Map<String, String> userVmDetails = _userVmDetailsDao.listDetailsKeyPairs(vm.getId());
|
||||
|
||||
if (userVmDetails != null) {
|
||||
|
|
|
|||
|
|
@ -777,12 +777,21 @@ public class TemplateServiceImpl implements TemplateService {
|
|||
String scheme = "http";
|
||||
boolean _sslCopy = false;
|
||||
String sslCfg = _configDao.getValue(Config.SecStorageEncryptCopy.toString());
|
||||
String _ssvmUrlDomain = _configDao.getValue("secstorage.ssl.cert.domain");
|
||||
if (sslCfg != null) {
|
||||
_sslCopy = Boolean.parseBoolean(sslCfg);
|
||||
}
|
||||
if(_sslCopy && (_ssvmUrlDomain == null || _ssvmUrlDomain.isEmpty())){
|
||||
s_logger.warn("Empty secondary storage url domain, ignoring SSL");
|
||||
_sslCopy = false;
|
||||
}
|
||||
if (_sslCopy) {
|
||||
hostname = ipAddress.replace(".", "-");
|
||||
hostname = hostname + ".realhostip.com";
|
||||
if(_ssvmUrlDomain.startsWith("*")) {
|
||||
hostname = ipAddress.replace(".", "-");
|
||||
hostname = hostname + _ssvmUrlDomain.substring(1);
|
||||
} else {
|
||||
hostname = _ssvmUrlDomain;
|
||||
}
|
||||
scheme = "https";
|
||||
}
|
||||
return scheme + "://" + hostname + "/copy/SecStorage/" + dir + "/" + path;
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
# set environment variables
|
||||
|
||||
SHORTNAME="$0"
|
||||
SHORTNAME="basename $0"
|
||||
PIDFILE=/var/run/"$SHORTNAME".pid
|
||||
LOCKFILE=/var/lock/subsys/"$SHORTNAME"
|
||||
LOGDIR=/var/log/cloudstack/agent
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
# set environment variables
|
||||
|
||||
SHORTNAME="$0"
|
||||
SHORTNAME="basename $0"
|
||||
PIDFILE=/var/run/"$SHORTNAME".pid
|
||||
LOCKFILE=/var/lock/subsys/"$SHORTNAME"
|
||||
LOGFILE=/var/log/cloudstack/ipallocator/ipallocator.log
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ import com.cloud.host.HostVO;
|
|||
import com.cloud.host.dao.HostDao;
|
||||
import com.cloud.hypervisor.Hypervisor.HypervisorType;
|
||||
import com.cloud.storage.GuestOSVO;
|
||||
import com.cloud.storage.Volume;
|
||||
import com.cloud.storage.VolumeVO;
|
||||
import com.cloud.storage.dao.GuestOSDao;
|
||||
import com.cloud.storage.dao.VolumeDao;
|
||||
|
|
@ -103,30 +102,30 @@ public class XenServerGuru extends HypervisorGuruBase implements HypervisorGuru
|
|||
|
||||
List<VolumeVO> volumes = _volumeDao.findByInstance(vm.getId());
|
||||
|
||||
// it's OK in this case to send a detach command to the host for a root volume as this
|
||||
// will simply lead to the SR that supports the root volume being removed
|
||||
if (volumes != null) {
|
||||
for (VolumeVO volume : volumes) {
|
||||
if (volume.getVolumeType() == Volume.Type.DATADISK) {
|
||||
StoragePoolVO storagePool = _storagePoolDao.findById(volume.getPoolId());
|
||||
StoragePoolVO storagePool = _storagePoolDao.findById(volume.getPoolId());
|
||||
|
||||
// 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());
|
||||
// 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());
|
||||
|
||||
DettachCommand cmd = new DettachCommand(disk, vm.getInstanceName());
|
||||
DettachCommand cmd = new DettachCommand(disk, vm.getInstanceName());
|
||||
|
||||
cmd.setManaged(true);
|
||||
cmd.setManaged(true);
|
||||
|
||||
cmd.setStorageHost(storagePool.getHostAddress());
|
||||
cmd.setStoragePort(storagePool.getPort());
|
||||
cmd.setStorageHost(storagePool.getHostAddress());
|
||||
cmd.setStoragePort(storagePool.getPort());
|
||||
|
||||
cmd.set_iScsiName(volume.get_iScsiName());
|
||||
cmd.set_iScsiName(volume.get_iScsiName());
|
||||
|
||||
commands.add(cmd);
|
||||
}
|
||||
commands.add(cmd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -93,12 +93,16 @@ public class CloudStackImageStoreDriverImpl extends BaseImageStoreDriverImpl {
|
|||
if (sslCfg != null) {
|
||||
_sslCopy = Boolean.parseBoolean(sslCfg);
|
||||
}
|
||||
if(_sslCopy && (_ssvmUrlDomain == null || _ssvmUrlDomain.isEmpty())){
|
||||
s_logger.warn("Empty secondary storage url domain, ignoring SSL");
|
||||
_sslCopy = false;
|
||||
}
|
||||
if (_sslCopy) {
|
||||
hostname = ipAddress.replace(".", "-");
|
||||
if (_ssvmUrlDomain != null && _ssvmUrlDomain.length() > 0) {
|
||||
hostname = hostname + "." + _ssvmUrlDomain;
|
||||
if(_ssvmUrlDomain.startsWith("*")) {
|
||||
hostname = ipAddress.replace(".", "-");
|
||||
hostname = hostname + _ssvmUrlDomain.substring(1);
|
||||
} else {
|
||||
hostname = hostname + ".realhostip.com";
|
||||
hostname = _ssvmUrlDomain;
|
||||
}
|
||||
scheme = "https";
|
||||
}
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
# set environment variables
|
||||
|
||||
SHORTNAME="$0"
|
||||
SHORTNAME="basename $0"
|
||||
PIDFILE=@PIDDIR@/"$SHORTNAME".pid
|
||||
LOCKFILE=@LOCKDIR@/"$SHORTNAME"
|
||||
LOGFILE=@IPALOCATORLOG@
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
# set environment variables
|
||||
|
||||
SHORTNAME="$0"
|
||||
SHORTNAME="basename $0"
|
||||
PIDFILE=@PIDDIR@/"$SHORTNAME".pid
|
||||
LOCKFILE=@LOCKDIR@/"$SHORTNAME"
|
||||
LOGFILE=@AGENTLOG@
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
# set environment variables
|
||||
|
||||
SHORTNAME="$0"
|
||||
SHORTNAME="basename $0"
|
||||
PIDFILE=@PIDDIR@/"$SHORTNAME".pid
|
||||
LOCKFILE=@LOCKDIR@/"$SHORTNAME"
|
||||
LOGFILE=@AGENTLOG@
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
# set environment variables
|
||||
|
||||
SHORTNAME="$0"
|
||||
SHORTNAME="basename $0"
|
||||
PIDFILE=@PIDDIR@/"$SHORTNAME".pid
|
||||
LOCKFILE=@LOCKDIR@/"$SHORTNAME"
|
||||
LOGFILE=@AGENTLOG@
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
# set environment variables
|
||||
|
||||
SHORTNAME="$0"
|
||||
SHORTNAME="basename $0"
|
||||
PIDFILE=@PIDDIR@/"$SHORTNAME".pid
|
||||
LOCKFILE=@LOCKDIR@/"$SHORTNAME"
|
||||
LOGFILE=@AGENTLOG@
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
# set environment variables
|
||||
|
||||
SHORTNAME="$0"
|
||||
SHORTNAME="basename $0"
|
||||
PIDFILE=@PIDDIR@/"$SHORTNAME".pid
|
||||
LOCKFILE=@LOCKDIR@/"$SHORTNAME"
|
||||
LOGFILE=@AGENTLOG@
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import java.util.Map;
|
|||
import javax.annotation.PostConstruct;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.event.EventTypes;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
import org.apache.cloudstack.api.BaseAsyncCmd;
|
||||
import org.apache.cloudstack.api.BaseAsyncCreateCmd;
|
||||
|
|
@ -82,8 +83,14 @@ public class ApiDispatcher {
|
|||
|
||||
final BaseAsyncCmd asyncCmd = (BaseAsyncCmd)cmd;
|
||||
final String startEventId = params.get(ApiConstants.CTX_START_EVENT_ID);
|
||||
String uuid = params.get("uuid");
|
||||
ctx.setStartEventId(Long.valueOf(startEventId));
|
||||
|
||||
// Fow now use the key from EventTypes.java rather than getInstanceType bcz the later doesn't refer to the interfaces
|
||||
if(EventTypes.getEntityForEvent(asyncCmd.getEventType()) != null){
|
||||
ctx.putContextParameter(EventTypes.getEntityForEvent(asyncCmd.getEventType()), uuid);
|
||||
}
|
||||
|
||||
// Synchronise job on the object if needed
|
||||
if (asyncCmd.getJob() != null && asyncCmd.getSyncObjId() != null && asyncCmd.getSyncObjType() != null) {
|
||||
Long queueSizeLimit = null;
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@ import javax.naming.ConfigurationException;
|
|||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpSession;
|
||||
|
||||
import com.cloud.event.EventTypes;
|
||||
import org.apache.cloudstack.acl.APIChecker;
|
||||
import org.apache.cloudstack.api.APICommand;
|
||||
import org.apache.cloudstack.api.ApiConstants;
|
||||
|
|
@ -517,6 +518,8 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
|
|||
objectUuid = createCmd.getEntityUuid();
|
||||
params.put("id", objectId.toString());
|
||||
} else {
|
||||
// Extract the uuid before params are processed and id reflects internal db id
|
||||
objectUuid = params.get("id");
|
||||
dispatchChainFactory.getStandardDispatchChain().dispatch(new DispatchTask(cmdObj, params));
|
||||
}
|
||||
|
||||
|
|
@ -528,10 +531,16 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
|
|||
if (caller != null) {
|
||||
params.put("ctxAccountId", String.valueOf(caller.getId()));
|
||||
}
|
||||
if(objectUuid != null){
|
||||
params.put("uuid", objectUuid);
|
||||
}
|
||||
|
||||
long startEventId = ctx.getStartEventId();
|
||||
asyncCmd.setStartEventId(startEventId);
|
||||
|
||||
if(EventTypes.getEntityForEvent(asyncCmd.getEventType()) != null){
|
||||
ctx.putContextParameter(EventTypes.getEntityForEvent(asyncCmd.getEventType()), objectUuid);
|
||||
}
|
||||
// save the scheduled event
|
||||
final Long eventId =
|
||||
ActionEventUtils.onScheduledActionEvent((callerUserId == null) ? User.UID_SYSTEM : callerUserId, asyncCmd.getEntityOwnerId(), asyncCmd.getEventType(),
|
||||
|
|
@ -577,7 +586,7 @@ public class ApiServer extends ManagerBase implements HttpRequestHandler, ApiSer
|
|||
!(cmdObj instanceof ListVolumesCmd) && !(cmdObj instanceof ListUsersCmd) && !(cmdObj instanceof ListAccountsCmd) &&
|
||||
!(cmdObj instanceof ListStoragePoolsCmd) && !(cmdObj instanceof ListDiskOfferingsCmd) && !(cmdObj instanceof ListServiceOfferingsCmd) &&
|
||||
!(cmdObj instanceof ListZonesByCmd)) {
|
||||
buildAsyncListResponse((BaseListCmd)cmdObj, caller);
|
||||
buildAsyncListResponse((BaseListCmd) cmdObj, caller);
|
||||
}
|
||||
|
||||
SerializationContext.current().setUuidTranslation(true);
|
||||
|
|
|
|||
|
|
@ -37,9 +37,9 @@ import org.apache.log4j.Logger;
|
|||
*/
|
||||
public class ParamGenericValidationWorker implements DispatchWorker {
|
||||
|
||||
protected static Logger s_logger = Logger.getLogger(ParamGenericValidationWorker.class.getName());
|
||||
static Logger s_logger = Logger.getLogger(ParamGenericValidationWorker.class.getName());
|
||||
|
||||
protected static List<String> defaultParamNames = new ArrayList<String>();
|
||||
protected static final List<String> defaultParamNames = new ArrayList<String>();
|
||||
|
||||
static {
|
||||
defaultParamNames.add(ApiConstants.CTX_START_EVENT_ID);
|
||||
|
|
|
|||
|
|
@ -439,7 +439,7 @@ public enum Config {
|
|||
"Console proxy command port that is used to communicate with management server",
|
||||
null),
|
||||
ConsoleProxyRestart("Console Proxy", AgentManager.class, Boolean.class, "consoleproxy.restart", "true", "Console proxy restart flag, defaulted to true", null),
|
||||
ConsoleProxyUrlDomain("Console Proxy", AgentManager.class, String.class, "consoleproxy.url.domain", "realhostip.com", "Console proxy url domain", null),
|
||||
ConsoleProxyUrlDomain("Console Proxy", AgentManager.class, String.class, "consoleproxy.url.domain", "", "Console proxy url domain", null),
|
||||
ConsoleProxyLoadscanInterval(
|
||||
"Console Proxy",
|
||||
AgentManager.class,
|
||||
|
|
@ -782,7 +782,7 @@ public enum Config {
|
|||
ManagementServer.class,
|
||||
String.class,
|
||||
"secstorage.ssl.cert.domain",
|
||||
"realhostip.com",
|
||||
"",
|
||||
"SSL certificate used to encrypt copy traffic between zones",
|
||||
null),
|
||||
SecStorageCapacityStandby(
|
||||
|
|
|
|||
|
|
@ -233,6 +233,7 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
|
|||
|
||||
private int _proxySessionTimeoutValue = DEFAULT_PROXY_SESSION_TIMEOUT;
|
||||
private boolean _sslEnabled = true;
|
||||
private String _consoleProxyUrlDomain;
|
||||
|
||||
// global load picture at zone basis
|
||||
private SystemVmLoadScanner<Long> _loadScanner;
|
||||
|
|
@ -384,9 +385,9 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
|
|||
assert (ksVo != null);
|
||||
|
||||
if (_staticPublicIp == null) {
|
||||
return new ConsoleProxyInfo(proxy.isSslEnabled(), proxy.getPublicIpAddress(), _consoleProxyPort, proxy.getPort(), ksVo.getDomainSuffix());
|
||||
return new ConsoleProxyInfo(proxy.isSslEnabled(), proxy.getPublicIpAddress(), _consoleProxyPort, proxy.getPort(), _consoleProxyUrlDomain);
|
||||
} else {
|
||||
return new ConsoleProxyInfo(proxy.isSslEnabled(), _staticPublicIp, _consoleProxyPort, _staticPort, ksVo.getDomainSuffix());
|
||||
return new ConsoleProxyInfo(proxy.isSslEnabled(), _staticPublicIp, _consoleProxyPort, _staticPort, _consoleProxyUrlDomain);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1191,6 +1192,12 @@ public class ConsoleProxyManagerImpl extends ManagerBase implements ConsoleProxy
|
|||
_sslEnabled = true;
|
||||
}
|
||||
|
||||
_consoleProxyUrlDomain = configs.get(Config.ConsoleProxyUrlDomain.key());
|
||||
if( _sslEnabled && (_consoleProxyUrlDomain == null || _consoleProxyUrlDomain.isEmpty())) {
|
||||
s_logger.warn("Empty console proxy domain, explicitly disabling SSL");
|
||||
_sslEnabled = false;
|
||||
}
|
||||
|
||||
value = configs.get(Config.ConsoleProxyCapacityScanInterval.key());
|
||||
_capacityScanInterval = NumbersUtil.parseLong(value, DEFAULT_CAPACITY_SCAN_INTERVAL);
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ import java.util.Map;
|
|||
import javax.annotation.PostConstruct;
|
||||
import javax.inject.Inject;
|
||||
|
||||
import com.cloud.vm.VirtualMachine;
|
||||
import org.apache.log4j.Logger;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
|
||||
|
|
@ -186,13 +185,19 @@ public class ActionEventUtils {
|
|||
// get the entity details for which ActionEvent is generated
|
||||
String entityType = null;
|
||||
String entityUuid = null;
|
||||
CallContext context = CallContext.current();
|
||||
Class entityKey = getEntityKey(eventType);
|
||||
if (entityKey != null)
|
||||
{
|
||||
CallContext context = CallContext.current();
|
||||
//FIXME - Remove this
|
||||
entityUuid = (String)context.getContextParameter(entityKey);
|
||||
if (entityUuid != null)
|
||||
entityType = entityKey.getName();
|
||||
}else if (EventTypes.getEntityForEvent(eventType) != null){
|
||||
entityType = EventTypes.getEntityForEvent(eventType);
|
||||
if (entityType != null){
|
||||
entityUuid = (String)context.getContextParameter(entityType);
|
||||
}
|
||||
}
|
||||
|
||||
org.apache.cloudstack.framework.events.Event event =
|
||||
|
|
@ -240,6 +245,7 @@ public class ActionEventUtils {
|
|||
|
||||
private static Class getEntityKey(String eventType)
|
||||
{
|
||||
// FIXME - Remove this
|
||||
if (eventType.startsWith("DOMAIN."))
|
||||
{
|
||||
return Domain.class;
|
||||
|
|
@ -251,8 +257,6 @@ public class ActionEventUtils {
|
|||
else if (eventType.startsWith("USER."))
|
||||
{
|
||||
return User.class;
|
||||
}else if (eventType.startsWith("VM.")){
|
||||
return VirtualMachine.class;
|
||||
}
|
||||
|
||||
return null;
|
||||
|
|
|
|||
|
|
@ -693,7 +693,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
|
|||
errorMessage.append(", vlanId id=" + Arrays.toString(dedicatedVlanDbIds.toArray()));
|
||||
} else if (nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) {
|
||||
sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray());
|
||||
errorMessage.append(", vlanId id=" + nonDedicatedVlanDbIds.toArray());
|
||||
errorMessage.append(", vlanId id=" + Arrays.toString(nonDedicatedVlanDbIds.toArray()));
|
||||
} else {
|
||||
if (podId != null) {
|
||||
InsufficientAddressCapacityException ex = new InsufficientAddressCapacityException("Insufficient address capacity", Pod.class, podId);
|
||||
|
|
@ -733,7 +733,7 @@ public class IpAddressManagerImpl extends ManagerBase implements IpAddressManage
|
|||
if (useSystemIps && nonDedicatedVlanDbIds != null && !nonDedicatedVlanDbIds.isEmpty()) {
|
||||
fetchFromDedicatedRange = false;
|
||||
sc.setParameters("vlanId", nonDedicatedVlanDbIds.toArray());
|
||||
errorMessage.append(", vlanId id=" + nonDedicatedVlanDbIds.toArray());
|
||||
errorMessage.append(", vlanId id=" + Arrays.toString(nonDedicatedVlanDbIds.toArray()));
|
||||
addrs = _ipAddressDao.lockRows(sc, filter, true);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1533,28 +1533,34 @@ public class NetworkModelImpl extends ManagerBase implements NetworkModel {
|
|||
|
||||
@Override
|
||||
public void checkNetworkPermissions(Account owner, Network network) {
|
||||
// dahn 20140310: I was thinking of making this an assert but
|
||||
// as we hardly ever test with asserts I think
|
||||
// we better make sure at runtime.
|
||||
if (network == null) {
|
||||
throw new CloudRuntimeException("cannot check permissions on (Network) <null>");
|
||||
}
|
||||
// Perform account permission check
|
||||
if (network.getGuestType() != Network.GuestType.Shared || (network.getGuestType() == Network.GuestType.Shared && network.getAclType() == ACLType.Account)) {
|
||||
AccountVO networkOwner = _accountDao.findById(network.getAccountId());
|
||||
if (networkOwner == null)
|
||||
throw new PermissionDeniedException("Unable to use network with id= " + ((network != null) ? ((NetworkVO)network).getUuid() : "") +
|
||||
throw new PermissionDeniedException("Unable to use network with id= " + ((NetworkVO)network).getUuid() +
|
||||
", network does not have an owner");
|
||||
if (owner.getType() != Account.ACCOUNT_TYPE_PROJECT && networkOwner.getType() == Account.ACCOUNT_TYPE_PROJECT) {
|
||||
if (!_projectAccountDao.canAccessProjectAccount(owner.getAccountId(), network.getAccountId())) {
|
||||
throw new PermissionDeniedException("Unable to use network with id= " + ((network != null) ? ((NetworkVO)network).getUuid() : "") +
|
||||
throw new PermissionDeniedException("Unable to use network with id= " + ((NetworkVO)network).getUuid() +
|
||||
", permission denied");
|
||||
}
|
||||
} else {
|
||||
List<NetworkVO> networkMap = _networksDao.listBy(owner.getId(), network.getId());
|
||||
if (networkMap == null || networkMap.isEmpty()) {
|
||||
throw new PermissionDeniedException("Unable to use network with id= " + ((network != null) ? ((NetworkVO)network).getUuid() : "") +
|
||||
throw new PermissionDeniedException("Unable to use network with id= " + ((NetworkVO)network).getUuid() +
|
||||
", permission denied");
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (!isNetworkAvailableInDomain(network.getId(), owner.getDomainId())) {
|
||||
throw new PermissionDeniedException("Shared network id=" + ((network != null) ? ((NetworkVO)network).getUuid() : "") + " is not available in domain id=" +
|
||||
throw new PermissionDeniedException("Shared network id=" + ((NetworkVO)network).getUuid() + " is not available in domain id=" +
|
||||
owner.getDomainId());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ import com.cloud.network.Network;
|
|||
import com.cloud.network.Network.Capability;
|
||||
import com.cloud.network.Network.Provider;
|
||||
import com.cloud.network.Network.Service;
|
||||
import com.cloud.network.Network.State;
|
||||
import com.cloud.network.NetworkModel;
|
||||
import com.cloud.network.PublicIpAddress;
|
||||
import com.cloud.network.RemoteAccessVpn;
|
||||
|
|
@ -179,7 +180,11 @@ public class VpcVirtualRouterElement extends VirtualRouterElement implements Vpc
|
|||
DomainRouterVO router = routers.get(0);
|
||||
//Add router to guest network if needed
|
||||
if (!_networkMgr.isVmPartOfNetwork(router.getId(), network.getId())) {
|
||||
if (!_vpcRouterMgr.addVpcRouterToGuestNetwork(router, network, false)) {
|
||||
Map<VirtualMachineProfile.Param, Object> paramsForRouter = new HashMap<VirtualMachineProfile.Param, Object>(1);
|
||||
if (network.getState() == State.Setup) {
|
||||
paramsForRouter.put(VirtualMachineProfile.Param.ReProgramGuestNetworks, true);
|
||||
}
|
||||
if (!_vpcRouterMgr.addVpcRouterToGuestNetwork(router, network, false, paramsForRouter)) {
|
||||
throw new CloudRuntimeException("Failed to add VPC router " + router + " to guest network " + network);
|
||||
} else {
|
||||
s_logger.debug("Successfully added VPC router " + router + " to guest network " + network);
|
||||
|
|
@ -220,7 +225,12 @@ public class VpcVirtualRouterElement extends VirtualRouterElement implements Vpc
|
|||
DomainRouterVO router = routers.get(0);
|
||||
//Add router to guest network if needed
|
||||
if (!_networkMgr.isVmPartOfNetwork(router.getId(), network.getId())) {
|
||||
if (!_vpcRouterMgr.addVpcRouterToGuestNetwork(router, network, false)) {
|
||||
Map<VirtualMachineProfile.Param, Object> paramsForRouter = new HashMap<VirtualMachineProfile.Param, Object>(1);
|
||||
// need to reprogram guest network if it comes in a setup state
|
||||
if (network.getState() == State.Setup) {
|
||||
paramsForRouter.put(VirtualMachineProfile.Param.ReProgramGuestNetworks, true);
|
||||
}
|
||||
if (!_vpcRouterMgr.addVpcRouterToGuestNetwork(router, network, false, paramsForRouter)) {
|
||||
throw new CloudRuntimeException("Failed to add VPC router " + router + " to guest network " + network);
|
||||
} else {
|
||||
s_logger.debug("Successfully added VPC router " + router + " to guest network " + network);
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ import org.springframework.stereotype.Component;
|
|||
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.api.Command;
|
||||
import com.cloud.agent.api.Command.OnError;
|
||||
import com.cloud.agent.api.NetworkUsageCommand;
|
||||
import com.cloud.agent.api.PlugNicCommand;
|
||||
import com.cloud.agent.api.SetupGuestNetworkCommand;
|
||||
|
|
@ -246,9 +247,8 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean addVpcRouterToGuestNetwork(VirtualRouter router, Network network, boolean isRedundant) throws ConcurrentOperationException,
|
||||
ResourceUnavailableException, InsufficientCapacityException {
|
||||
|
||||
public boolean addVpcRouterToGuestNetwork(VirtualRouter router, Network network, boolean isRedundant, Map<VirtualMachineProfile.Param, Object> params)
|
||||
throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
|
||||
if (network.getTrafficType() != TrafficType.Guest) {
|
||||
s_logger.warn("Network " + network + " is not of type " + TrafficType.Guest);
|
||||
return false;
|
||||
|
|
@ -257,16 +257,23 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian
|
|||
//Add router to the Guest network
|
||||
boolean result = true;
|
||||
try {
|
||||
|
||||
// 1) add nic to the router
|
||||
_routerDao.addRouterToGuestNetwork(router, network);
|
||||
|
||||
NicProfile guestNic = _itMgr.addVmToNetwork(router, network, null);
|
||||
//setup guest network
|
||||
//2) setup guest network
|
||||
if (guestNic != null) {
|
||||
result = setupVpcGuestNetwork(network, router, true, guestNic);
|
||||
} else {
|
||||
s_logger.warn("Failed to add router " + router + " to guest network " + network);
|
||||
result = false;
|
||||
}
|
||||
//3) apply networking rules
|
||||
if (result && params.get(Param.ReProgramGuestNetworks) != null
|
||||
&& (Boolean) params.get(Param.ReProgramGuestNetworks) == true) {
|
||||
sendNetworkRulesToRouter(router.getId(), network.getId());
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
s_logger.warn("Failed to add router " + router + " to network " + network + " due to ", ex);
|
||||
result = false;
|
||||
|
|
@ -885,6 +892,25 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
protected boolean sendNetworkRulesToRouter(long routerId, long networkId)
|
||||
throws ResourceUnavailableException {
|
||||
DomainRouterVO router = _routerDao.findById(routerId);
|
||||
Commands cmds = new Commands(OnError.Continue);
|
||||
|
||||
VirtualRouterProvider vrProvider = _vrProviderDao.findById(router.getElementId());
|
||||
if (vrProvider == null) {
|
||||
throw new CloudRuntimeException("Cannot find related virtual router provider of router: " + router.getHostName());
|
||||
}
|
||||
Provider provider = Network.Provider.getProvider(vrProvider.getType().toString());
|
||||
if (provider == null) {
|
||||
throw new CloudRuntimeException("Cannot find related provider of virtual router provider: " + vrProvider.getType().toString());
|
||||
}
|
||||
|
||||
finalizeNetworkRulesForNetwork(cmds, router, provider, networkId);
|
||||
return sendCommandsToRouter(router, cmds);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setupPrivateGateway(PrivateGateway gateway, VirtualRouter router) throws ConcurrentOperationException, ResourceUnavailableException {
|
||||
boolean result = true;
|
||||
|
|
|
|||
|
|
@ -424,14 +424,14 @@ public class VpcManagerImpl extends ManagerBase implements VpcManager, VpcProvis
|
|||
List<VpcOfferingServiceMapVO> map = _vpcOffSvcMapDao.listByVpcOffId(vpcOffId);
|
||||
|
||||
for (VpcOfferingServiceMapVO instance : map) {
|
||||
String service = instance.getService();
|
||||
Service service = Service.getService(instance.getService());
|
||||
Set<Provider> providers;
|
||||
providers = serviceProviderMap.get(service);
|
||||
if (providers == null) {
|
||||
providers = new HashSet<Provider>();
|
||||
}
|
||||
providers.add(Provider.getProvider(instance.getProvider()));
|
||||
serviceProviderMap.put(Service.getService(service), providers);
|
||||
serviceProviderMap.put(service, providers);
|
||||
}
|
||||
|
||||
return serviceProviderMap;
|
||||
|
|
|
|||
|
|
@ -3002,7 +3002,6 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
|
|||
long vmId = cmd.getEntityId();
|
||||
Long hostId = cmd.getHostId();
|
||||
UserVmVO vm = _vmDao.findById(vmId);
|
||||
CallContext.current().putContextParameter(VirtualMachine.class, vm.getUuid());
|
||||
|
||||
Pair<UserVmVO, Map<VirtualMachineProfile.Param, Object>> vmParamPair = null;
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* 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.network.vpc;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import com.cloud.network.Network.Provider;
|
||||
import com.cloud.network.Network.Service;
|
||||
import com.cloud.network.vpc.dao.VpcOfferingServiceMapDao;
|
||||
|
||||
public class VpcManagerImplTest {
|
||||
|
||||
@Mock
|
||||
VpcOfferingServiceMapDao vpcOffSvcMapDao;
|
||||
VpcManagerImpl manager;
|
||||
|
||||
@Before
|
||||
public void setup()
|
||||
{
|
||||
MockitoAnnotations.initMocks(this);
|
||||
manager = new VpcManagerImpl();
|
||||
manager._vpcOffSvcMapDao = vpcOffSvcMapDao;
|
||||
}
|
||||
@Test
|
||||
public void getVpcOffSvcProvidersMapForEmptyServiceTest() {
|
||||
long vpcOffId = 1L;
|
||||
List<VpcOfferingServiceMapVO> list = new ArrayList<VpcOfferingServiceMapVO>();
|
||||
list.add(Mockito.mock(VpcOfferingServiceMapVO.class));
|
||||
when(manager._vpcOffSvcMapDao.listByVpcOffId(vpcOffId)).thenReturn(list);
|
||||
|
||||
Map<Service, Set<Provider>> map = manager.getVpcOffSvcProvidersMap(vpcOffId);
|
||||
|
||||
assertNotNull(map);
|
||||
assertEquals(map.size(),1);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -23,10 +23,9 @@ import java.util.Map;
|
|||
import javax.ejb.Local;
|
||||
import javax.naming.ConfigurationException;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import org.apache.cloudstack.api.command.admin.router.UpgradeRouterCmd;
|
||||
import org.apache.cloudstack.api.command.admin.router.UpgradeRouterTemplateCmd;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import com.cloud.deploy.DeployDestination;
|
||||
import com.cloud.exception.ConcurrentOperationException;
|
||||
|
|
@ -313,8 +312,8 @@ public class MockVpcVirtualNetworkApplianceManager extends ManagerBase implement
|
|||
* @see com.cloud.network.VpcVirtualNetworkApplianceService#addVpcRouterToGuestNetwork(com.cloud.network.router.VirtualRouter, com.cloud.network.Network, boolean)
|
||||
*/
|
||||
@Override
|
||||
public boolean addVpcRouterToGuestNetwork(VirtualRouter router, Network network, boolean isRedundant) throws ConcurrentOperationException,
|
||||
ResourceUnavailableException, InsufficientCapacityException {
|
||||
public boolean addVpcRouterToGuestNetwork(VirtualRouter router, Network network, boolean isRedundant, Map<VirtualMachineProfile.Param, Object> params)
|
||||
throws ConcurrentOperationException, ResourceUnavailableException, InsufficientCapacityException {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -807,6 +807,13 @@ public class SecondaryStorageManagerImpl extends ManagerBase implements Secondar
|
|||
_useSSlCopy = true;
|
||||
}
|
||||
|
||||
//default to HTTP in case of missing domain
|
||||
String ssvmUrlDomain = _configDao.getValue("secstorage.ssl.cert.domain");
|
||||
if(_useSSlCopy && (ssvmUrlDomain == null || ssvmUrlDomain.isEmpty())){
|
||||
s_logger.warn("Empty secondary storage url domain, explicitly disabling SSL");
|
||||
_useSSlCopy = false;
|
||||
}
|
||||
|
||||
_allowedInternalSites = _configDao.getValue("secstorage.allowed.internal.sites");
|
||||
|
||||
String value = configs.get("secstorage.capacityscan.interval");
|
||||
|
|
|
|||
|
|
@ -110,6 +110,10 @@ CREATE TABLE `cloud`.`async_job_join_map` (
|
|||
INDEX `i_async_job_join_map__expiration`(`expiration`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
|
||||
#realhostip changes, before changing table and adding default value
|
||||
UPDATE `cloud`.`configuration` SET value = CONCAT("*.",(SELECT `temptable`.`value` FROM (SELECT * FROM `cloud`.`configuration` WHERE `name`="consoleproxy.url.domain") AS `temptable` WHERE `temptable`.`name`="consoleproxy.url.domain")) WHERE `name`="consoleproxy.url.domain";
|
||||
UPDATE `cloud`.`configuration` SET `value` = CONCAT("*.",(SELECT `temptable`.`value` FROM (SELECT * FROM `cloud`.`configuration` WHERE `name`="secstorage.ssl.cert.domain") AS `temptable` WHERE `temptable`.`name`="secstorage.ssl.cert.domain")) WHERE `name`="secstorage.ssl.cert.domain";
|
||||
|
||||
ALTER TABLE `cloud`.`configuration` ADD COLUMN `default_value` VARCHAR(4095) COMMENT 'Default value for a configuration parameter';
|
||||
ALTER TABLE `cloud`.`configuration` ADD COLUMN `updated` datetime COMMENT 'Time this was updated by the server. null means this row is obsolete.';
|
||||
ALTER TABLE `cloud`.`configuration` ADD COLUMN `scope` VARCHAR(255) DEFAULT NULL COMMENT 'Can this parameter be scoped';
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
# under the License.
|
||||
|
||||
consoleproxy.tcpListenPort=0
|
||||
consoleproxy.httpListenPort=8088
|
||||
consoleproxy.httpListenPort=80
|
||||
consoleproxy.httpCmdListenPort=8001
|
||||
consoleproxy.jarDir=./applet/
|
||||
consoleproxy.viewerLinger=180
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
# set environment variables
|
||||
|
||||
SHORTNAME="$0"
|
||||
SHORTNAME="basename $0"
|
||||
PIDFILE=@PIDDIR@/"$SHORTNAME".pid
|
||||
LOCKFILE=@LOCKDIR@/"$SHORTNAME"
|
||||
LOGFILE=@CPLOG@
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
# set environment variables
|
||||
|
||||
SHORTNAME="$0"
|
||||
SHORTNAME="basename $0"
|
||||
PIDFILE=@PIDDIR@/"$SHORTNAME".pid
|
||||
LOCKFILE=@LOCKDIR@/"$SHORTNAME"
|
||||
LOGFILE=@CPLOG@
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
# set environment variables
|
||||
|
||||
SHORTNAME="$0"
|
||||
SHORTNAME="basename $0"
|
||||
PIDFILE=@PIDDIR@/"$SHORTNAME".pid
|
||||
LOCKFILE=@LOCKDIR@/"$SHORTNAME"
|
||||
LOGFILE=@CPLOG@
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@
|
|||
|
||||
# set environment variables
|
||||
|
||||
SHORTNAME="$0"
|
||||
SHORTNAME="basename $0"
|
||||
PIDFILE=@PIDDIR@/"$SHORTNAME".pid
|
||||
LOCKFILE=@LOCKDIR@/"$SHORTNAME"
|
||||
LOGFILE=@CPLOG@
|
||||
|
|
|
|||
|
|
@ -30,10 +30,11 @@ from marvin.integration.lib.base import (
|
|||
from marvin.integration.lib.common import (get_domain,
|
||||
get_zone,
|
||||
get_template,
|
||||
find_suitable_host,
|
||||
findSuitableHostForMigration,
|
||||
get_resource_type
|
||||
)
|
||||
from marvin.integration.lib.utils import cleanup_resources
|
||||
from marvin.codes import ERROR_NO_HOST_FOR_MIGRATION
|
||||
|
||||
class Services:
|
||||
"""Test resource limit services
|
||||
|
|
@ -329,7 +330,9 @@ class TestDomainCPULimitsUpdateResources(cloudstackTestCase):
|
|||
self.assertEqual(resource_count, expected_resource_count,
|
||||
"Initial resource count should match with the expected resource count")
|
||||
|
||||
host = find_suitable_host(self.apiclient, vm)
|
||||
host = findSuitableHostForMigration(self.apiclient, vm.id)
|
||||
if host is None:
|
||||
self.skipTest(ERROR_NO_HOST_FOR_MIGRATION)
|
||||
self.debug("Migrating instance: %s to host: %s" %
|
||||
(vm.name, host.name))
|
||||
try:
|
||||
|
|
@ -477,7 +480,9 @@ class TestDomainCPULimitsUpdateResources(cloudstackTestCase):
|
|||
self.assertEqual(resource_count_after_delete, expected_resource_count,
|
||||
"Resource count should match with the expected count")
|
||||
|
||||
host = find_suitable_host(self.apiclient, vm_2)
|
||||
host = findSuitableHostForMigration(self.apiclient, vm_2.id)
|
||||
if host is None:
|
||||
self.skipTest(ERROR_NO_HOST_FOR_MIGRATION)
|
||||
self.debug("Migrating instance: %s to host: %s" % (vm_2.name,
|
||||
host.name))
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -30,10 +30,11 @@ from marvin.integration.lib.base import (
|
|||
from marvin.integration.lib.common import (get_domain,
|
||||
get_zone,
|
||||
get_template,
|
||||
find_suitable_host,
|
||||
findSuitableHostForMigration,
|
||||
get_resource_type
|
||||
)
|
||||
from marvin.integration.lib.utils import cleanup_resources
|
||||
from marvin.codes import ERROR_NO_HOST_FOR_MIGRATION
|
||||
|
||||
|
||||
class Services:
|
||||
|
|
@ -251,7 +252,9 @@ class TestCPULimits(cloudstackTestCase):
|
|||
self.assertEqual(resource_count, expected_resource_count,
|
||||
"Resource count should match with the expected resource count")
|
||||
|
||||
host = find_suitable_host(self.apiclient, self.vm)
|
||||
host = findSuitableHostForMigration(self.apiclient, self.vm.id)
|
||||
if host is None:
|
||||
self.skipTest(ERROR_NO_HOST_FOR_MIGRATION)
|
||||
self.debug("Migrating instance: %s to host: %s" % (self.vm.name, host.name))
|
||||
try:
|
||||
self.vm.migrate(self.apiclient, host.id)
|
||||
|
|
@ -570,7 +573,9 @@ class TestDomainCPULimitsConfiguration(cloudstackTestCase):
|
|||
self.assertEqual(resource_count, expected_resource_count,
|
||||
"Initial resource count should with the expected resource count")
|
||||
|
||||
host = find_suitable_host(self.apiclient, vm)
|
||||
host = findSuitableHostForMigration(self.apiclient, vm.id)
|
||||
if host is None:
|
||||
self.skipTest(ERROR_NO_HOST_FOR_MIGRATION)
|
||||
self.debug("Migrating instance: %s to host: %s" %
|
||||
(vm.name, host.name))
|
||||
try:
|
||||
|
|
@ -725,7 +730,9 @@ class TestDomainCPULimitsConfiguration(cloudstackTestCase):
|
|||
self.assertEqual(resource_count_after_delete, expected_resource_count,
|
||||
"Resource count should be less than before after deleting the instance")
|
||||
|
||||
host = find_suitable_host(self.apiclient, vm_2)
|
||||
host = findSuitableHostForMigration(self.apiclient, vm_2.id)
|
||||
if host is None:
|
||||
self.skipTest(ERROR_NO_HOST_FOR_MIGRATION)
|
||||
self.debug("Migrating instance: %s to host: %s" % (vm_2.name,
|
||||
host.name))
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -30,10 +30,11 @@ from marvin.integration.lib.base import (
|
|||
from marvin.integration.lib.common import (get_domain,
|
||||
get_zone,
|
||||
get_template,
|
||||
find_suitable_host,
|
||||
findSuitableHostForMigration,
|
||||
get_resource_type
|
||||
)
|
||||
from marvin.integration.lib.utils import cleanup_resources
|
||||
from marvin.codes import ERROR_NO_HOST_FOR_MIGRATION
|
||||
|
||||
class Services:
|
||||
"""Test resource limit services
|
||||
|
|
@ -291,7 +292,9 @@ class TestProjectsCPULimits(cloudstackTestCase):
|
|||
self.assertEqual(resource_count, expected_resource_count,
|
||||
"Resource count should match with the expected resource count")
|
||||
|
||||
host = find_suitable_host(self.apiclient, self.vm)
|
||||
host = findSuitableHostForMigration(self.apiclient, self.vm.id)
|
||||
if host is None:
|
||||
self.skipTest(ERROR_NO_HOST_FOR_MIGRATION)
|
||||
self.debug("Migrating instance: %s to host: %s" %
|
||||
(self.vm.name, host.name))
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,409 @@
|
|||
# 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.
|
||||
|
||||
""" Tests for Dynamic Compute Offering Feature
|
||||
|
||||
Test Plan: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Dynamic+ComputeOffering
|
||||
|
||||
Issue Link: https://issues.apache.org/jira/browse/CLOUDSTACK-6147
|
||||
|
||||
Feature Specifications: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Dynamic+Compute+Offering+FS
|
||||
"""
|
||||
from marvin.cloudstackTestCase import cloudstackTestCase
|
||||
from marvin.integration.lib.utils import (cleanup_resources,
|
||||
validateList)
|
||||
from marvin.integration.lib.base import (ServiceOffering,
|
||||
VirtualMachine,
|
||||
Account)
|
||||
from marvin.integration.lib.common import (get_domain,
|
||||
get_zone,
|
||||
get_template,
|
||||
verifyComputeOfferingCreation)
|
||||
|
||||
from nose.plugins.attrib import attr
|
||||
from marvin.codes import PASS, ADMIN_ACCOUNT, USER_ACCOUNT
|
||||
from ddt import ddt, data
|
||||
|
||||
@ddt
|
||||
class TestDynamicServiceOffering(cloudstackTestCase):
|
||||
"""Test Dynamic Service Offerings
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
cloudstackTestClient = super(TestDynamicServiceOffering,cls).getClsTestClient()
|
||||
cls.api_client = cloudstackTestClient.getApiClient()
|
||||
|
||||
# Fill services from the external config file
|
||||
cls.services = cloudstackTestClient.getConfigParser().parsedDict
|
||||
|
||||
# Get Zone, Domain and templates
|
||||
cls.domain = get_domain(cls.api_client, cls.services)
|
||||
cls.zone = get_zone(cls.api_client, cls.services)
|
||||
cls.mode = str(cls.zone.networktype).lower()
|
||||
cls.template = get_template(
|
||||
cls.api_client,
|
||||
cls.zone.id,
|
||||
cls.services["ostype"]
|
||||
)
|
||||
cls.services["virtual_machine"]["zoneid"] = cls.zone.id
|
||||
cls.services["virtual_machine"]["template"] = cls.template.id
|
||||
cls._cleanup = []
|
||||
return
|
||||
|
||||
@classmethod
|
||||
def tearDownClass(cls):
|
||||
try:
|
||||
# Cleanup resources used
|
||||
cleanup_resources(cls.api_client, cls._cleanup)
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
return
|
||||
|
||||
def setUp(self):
|
||||
self.apiclient = self.testClient.getApiClient()
|
||||
self.dbclient = self.testClient.getDbConnection()
|
||||
self.cleanup_co = []
|
||||
self.cleanup = []
|
||||
return
|
||||
|
||||
def tearDown(self):
|
||||
try:
|
||||
# Clean up compute offerings
|
||||
cleanup_resources(self.apiclient, self.cleanup)
|
||||
|
||||
# Clean up compute offerings
|
||||
cleanup_resources(self.apiclient, self.cleanup_co)
|
||||
|
||||
self.cleanup_co[:] = []
|
||||
self.cleanup[:] = []
|
||||
except Exception as e:
|
||||
raise Exception("Warning: Exception during cleanup : %s" % e)
|
||||
return
|
||||
|
||||
@attr(tags=["basic","advanced"])
|
||||
def test_create_normal_compute_offering(self):
|
||||
""" Create normal compute offering with non zero values for cpu,
|
||||
cpu number and memory"""
|
||||
|
||||
# Steps:
|
||||
# 1. Create normal compute offering with non zero values for cpu number,
|
||||
# cpu speed, memory
|
||||
|
||||
# Validations:
|
||||
# 1. Compute offering should be created
|
||||
|
||||
self.services["service_offering"]["cpunumber"] = 2
|
||||
self.services["service_offering"]["cpuspeed"] = 256
|
||||
self.services["service_offering"]["memory"] = 128
|
||||
|
||||
serviceOffering = ServiceOffering.create(self.api_client,
|
||||
self.services["service_offering"]
|
||||
)
|
||||
self.assertEqual(verifyComputeOfferingCreation(self.apiclient, serviceOffering.id),
|
||||
PASS, "Compute Offering verification failed")
|
||||
|
||||
self.cleanup_co.append(serviceOffering)
|
||||
return
|
||||
|
||||
@attr(tags=["basic","advanced"])
|
||||
def test_create_dynamic_compute_offering(self):
|
||||
""" Create dynamic compute offering with cpunumber, cpuspeed and memory
|
||||
not specified"""
|
||||
|
||||
# Steps:
|
||||
# 1. Create dynamic compute offering with values for cpu number,
|
||||
# cpu speed, memory not specified
|
||||
|
||||
# Validations:
|
||||
# 1. Compute offering should be created
|
||||
|
||||
self.services["service_offering"]["cpunumber"] = ""
|
||||
self.services["service_offering"]["cpuspeed"] = ""
|
||||
self.services["service_offering"]["memory"] = ""
|
||||
|
||||
serviceOffering = ServiceOffering.create(self.api_client,
|
||||
self.services["service_offering"]
|
||||
)
|
||||
self.assertEqual(verifyComputeOfferingCreation(self.apiclient, serviceOffering.id),
|
||||
PASS, "Compute Offering verification failed")
|
||||
|
||||
self.cleanup_co.append(serviceOffering)
|
||||
return
|
||||
|
||||
@attr(tags=["basic","advanced"])
|
||||
def test_create_dynamic_compute_offering_no_cpunumber(self):
|
||||
""" Create dynamic compute offering with only cpunumber unspecified"""
|
||||
|
||||
# Validations:
|
||||
# 1. Compute Offering creation should fail
|
||||
|
||||
self.services["service_offering"]["cpunumber"] = ""
|
||||
self.services["service_offering"]["cpuspeed"] = 256
|
||||
self.services["service_offering"]["memory"] = 128
|
||||
|
||||
try:
|
||||
serviceOffering = ServiceOffering.create(self.api_client,
|
||||
self.services["service_offering"]
|
||||
)
|
||||
self.cleanup_co.append(serviceOffering)
|
||||
self.fail("Compute Offering creation succeded, it should have failed")
|
||||
except Exception:
|
||||
self.debug("Compute Offering Creation failed as expected")
|
||||
return
|
||||
|
||||
@attr(tags=["basic","advanced"])
|
||||
def test_create_dynamic_compute_offering_no_cpuspeed(self):
|
||||
""" Create dynamic compute offering with only cpuspeed unspecified"""
|
||||
|
||||
# Validations:
|
||||
# 1. Compute offering creation should fail
|
||||
|
||||
self.services["service_offering"]["cpunumber"] = 2
|
||||
self.services["service_offering"]["cpuspeed"] = ""
|
||||
self.services["service_offering"]["memory"] = 128
|
||||
|
||||
try:
|
||||
serviceOffering = ServiceOffering.create(self.api_client,
|
||||
self.services["service_offering"]
|
||||
)
|
||||
self.cleanup_co.append(serviceOffering)
|
||||
self.fail("Compute Offering creation succeded, it should have failed")
|
||||
except Exception:
|
||||
self.debug("Compute Offering Creation failed as expected")
|
||||
return
|
||||
|
||||
@attr(tags=["basic","advanced"])
|
||||
def test_create_dynamic_compute_offering_no_memory(self):
|
||||
""" Create dynamic compute offering with only memory unspecified"""
|
||||
|
||||
# Validations:
|
||||
# 1. Compute offering creation should fail
|
||||
|
||||
self.services["service_offering"]["cpunumber"] = 2
|
||||
self.services["service_offering"]["cpuspeed"] = 256
|
||||
self.services["service_offering"]["memory"] = ""
|
||||
|
||||
try:
|
||||
serviceOffering = ServiceOffering.create(self.api_client,
|
||||
self.services["service_offering"]
|
||||
)
|
||||
self.cleanup_co.append(serviceOffering)
|
||||
self.fail("Compute Offering creation succeded, it should have failed")
|
||||
except Exception:
|
||||
self.debug("Compute Offering Creation failed as expected")
|
||||
return
|
||||
|
||||
@data(ADMIN_ACCOUNT, USER_ACCOUNT)
|
||||
@attr(tags=["basic","advanced"])
|
||||
def test_deploy_virtual_machines_static_offering(self, value):
|
||||
"""Test deploy VM with static offering"""
|
||||
|
||||
# Steps:
|
||||
# 1. Create admin/user account and create its user api client
|
||||
# 2. Create a static compute offering
|
||||
# 3. Deploy a VM with account api client and static service offering
|
||||
# 4. Repeat step 3 but also pass custom values for cpu number, cpu speed and memory
|
||||
# while deploying VM
|
||||
|
||||
# Validations:
|
||||
# 1. Step 3 should succeed
|
||||
# 2. Step 4 should fail
|
||||
|
||||
isadmin=True
|
||||
if value == USER_ACCOUNT:
|
||||
isadmin=False
|
||||
|
||||
# Create Account
|
||||
self.account = Account.create(self.apiclient,self.services["account"],domainid=self.domain.id, admin=isadmin)
|
||||
apiclient = self.testClient.createUserApiClient(
|
||||
UserName=self.account.name,
|
||||
DomainName=self.account.domain)
|
||||
self.cleanup.append(self.account)
|
||||
|
||||
# Create service offering
|
||||
self.services["service_offering"]["cpunumber"] = 2
|
||||
self.services["service_offering"]["cpuspeed"] = 256
|
||||
self.services["service_offering"]["memory"] = 128
|
||||
|
||||
serviceOffering = ServiceOffering.create(self.apiclient,
|
||||
self.services["service_offering"])
|
||||
|
||||
self.cleanup_co.append(serviceOffering)
|
||||
|
||||
# Deploy VM with static service offering
|
||||
try:
|
||||
VirtualMachine.create(apiclient,self.services["virtual_machine"],
|
||||
serviceofferingid=serviceOffering.id,
|
||||
accountid=self.account.name,domainid=self.account.domainid)
|
||||
except Exception as e:
|
||||
self.fail("vm creation failed: %s" % e)
|
||||
|
||||
# Deploy VM with static service offering, also with custom values
|
||||
try:
|
||||
VirtualMachine.create(apiclient,self.services["virtual_machine"],
|
||||
serviceofferingid=serviceOffering.id,
|
||||
customcpunumber=4,
|
||||
customcpuspeed=512,
|
||||
custommemory=256,
|
||||
accountid=self.account.name,domainid=self.account.domainid)
|
||||
self.fail("VM creation should have failed, it succeeded")
|
||||
except Exception as e:
|
||||
self.debug("vm creation failed as expected: %s" % e)
|
||||
return
|
||||
|
||||
@data(ADMIN_ACCOUNT, USER_ACCOUNT)
|
||||
@attr(tags=["basic","advanced"])
|
||||
def test_deploy_virtual_machines_dynamic_offering(self, value):
|
||||
"""Test deploy VM with dynamic compute offering"""
|
||||
|
||||
# Steps:
|
||||
# 1. Create admin/user account and create its user api client
|
||||
# 2. Create a dynamic service offering
|
||||
# 3. Deploy a VM with account api client and dynamic service offering
|
||||
# without providing custom values for cpu number, cpu speed and memory
|
||||
# 4. Deploy a VM with account api client and dynamic service offering providing
|
||||
# custom values for cpu number, cpu speed and memory
|
||||
# 5. Deploy a VM with account api client and dynamic service offering providing
|
||||
# custom values only for cpu number
|
||||
|
||||
# Validations:
|
||||
# 1. Step 3 should fail
|
||||
# 2. Step 4 should succeed
|
||||
# 3. Step 5 should fail
|
||||
|
||||
isadmin=True
|
||||
if value == USER_ACCOUNT:
|
||||
isadmin=False
|
||||
|
||||
# Create Account and its api client
|
||||
self.account = Account.create(self.apiclient,self.services["account"],domainid=self.domain.id, admin=isadmin)
|
||||
apiclient = self.testClient.createUserApiClient(
|
||||
UserName=self.account.name,
|
||||
DomainName=self.account.domain)
|
||||
self.cleanup.append(self.account)
|
||||
|
||||
# Create dynamic service offering
|
||||
self.services["service_offering"]["cpunumber"] = ""
|
||||
self.services["service_offering"]["cpuspeed"] = ""
|
||||
self.services["service_offering"]["memory"] = ""
|
||||
|
||||
serviceOffering = ServiceOffering.create(self.apiclient,
|
||||
self.services["service_offering"])
|
||||
|
||||
self.cleanup_co.append(serviceOffering)
|
||||
|
||||
# Deploy VM with dynamic compute offering without providing custom values for
|
||||
# cpu number, cpu speed and memory
|
||||
try:
|
||||
VirtualMachine.create(apiclient,self.services["virtual_machine"],
|
||||
serviceofferingid=serviceOffering.id,
|
||||
accountid=self.account.name,domainid=self.account.domainid)
|
||||
self.fail("VM creation succeded, it should have failed")
|
||||
except Exception as e:
|
||||
self.debug("vm creation failed as expected with error: %s" % e)
|
||||
|
||||
# Deploy VM with dynamic compute offering providing custom values for
|
||||
# cpu number, cpu speed and memory
|
||||
try:
|
||||
VirtualMachine.create(apiclient,self.services["virtual_machine"],
|
||||
serviceofferingid=serviceOffering.id,
|
||||
customcpunumber=2,
|
||||
customcpuspeed=256,
|
||||
custommemory=128,
|
||||
accountid=self.account.name,domainid=self.account.domainid)
|
||||
except Exception as e:
|
||||
self.fail("vm creation failed: %s" % e)
|
||||
|
||||
# Deploy VM with dynamic compute offering providing custom values for only
|
||||
# cpu number
|
||||
try:
|
||||
VirtualMachine.create(apiclient,self.services["virtual_machine"],
|
||||
serviceofferingid=serviceOffering.id,
|
||||
customcpunumber=2,
|
||||
accountid=self.account.name,domainid=self.account.domainid)
|
||||
self.fail("VM deployment should have failed, it succeded")
|
||||
except Exception as e:
|
||||
self.debug("vm creation failed as expected: %s" % e)
|
||||
return
|
||||
|
||||
@data(ADMIN_ACCOUNT, USER_ACCOUNT)
|
||||
@attr(tags=["basic","advanced"])
|
||||
def test_check_vm_stats(self, value):
|
||||
"""Deploy VM with dynamic service offering and check VM stats"""
|
||||
|
||||
# Steps:
|
||||
# 1. Create admin/user account and create its user api client
|
||||
# 2. Create a dynamic service offering
|
||||
# 3. Deploy a VM with account api client and dynamic service offering
|
||||
# providing custom values for cpu number, cpu speed and memory
|
||||
# 4. List the VM and verify the dynamic parameters are same as passed
|
||||
|
||||
isadmin=True
|
||||
if value == USER_ACCOUNT:
|
||||
isadmin=False
|
||||
|
||||
# Create Account and api client
|
||||
self.account = Account.create(self.apiclient,self.services["account"],domainid=self.domain.id, admin=isadmin)
|
||||
apiclient = self.testClient.createUserApiClient(
|
||||
UserName=self.account.name,
|
||||
DomainName=self.account.domain)
|
||||
self.cleanup.append(self.account)
|
||||
|
||||
# Create dynamic compute offering
|
||||
self.services["service_offering"]["cpunumber"] = ""
|
||||
self.services["service_offering"]["cpuspeed"] = ""
|
||||
self.services["service_offering"]["memory"] = ""
|
||||
|
||||
serviceOffering = ServiceOffering.create(self.apiclient,
|
||||
self.services["service_offering"])
|
||||
|
||||
self.cleanup_co.append(serviceOffering)
|
||||
|
||||
# Custom values
|
||||
customcpunumber = 2
|
||||
customcpuspeed = 256
|
||||
custommemory = 128
|
||||
|
||||
# Deploy VM with dynamic service offering and the custom values
|
||||
try:
|
||||
virtualMachine = VirtualMachine.create(apiclient,self.services["virtual_machine"],
|
||||
serviceofferingid=serviceOffering.id,
|
||||
customcpunumber=customcpunumber,
|
||||
customcpuspeed=customcpuspeed,
|
||||
custommemory=custommemory,
|
||||
accountid=self.account.name,domainid=self.account.domainid)
|
||||
except Exception as e:
|
||||
self.fail("vm creation failed: %s" % e)
|
||||
|
||||
vmlist = VirtualMachine.list(self.apiclient, id=virtualMachine.id)
|
||||
self.assertEqual(validateList(vmlist)[0], PASS, "vm list validation failed")
|
||||
vm = vmlist[0]
|
||||
|
||||
# Verify the custom values
|
||||
self.assertEqual(str(vm.cpunumber), str(customcpunumber), "vm cpu number %s\
|
||||
not matching with provided custom cpu number %s" % \
|
||||
(vm.cpunumber, customcpunumber))
|
||||
|
||||
self.assertEqual(str(vm.cpuspeed), str(customcpuspeed), "vm cpu speed %s\
|
||||
not matching with provided custom cpu speed %s" % \
|
||||
(vm.cpuspeed, customcpuspeed))
|
||||
|
||||
self.assertEqual(str(vm.memory), str(custommemory), "vm memory %s\
|
||||
not matching with provided custom memory %s" % \
|
||||
(vm.memory, custommemory))
|
||||
return
|
||||
|
|
@ -30,10 +30,11 @@ from marvin.integration.lib.common import (get_domain,
|
|||
get_zone,
|
||||
get_template,
|
||||
wait_for_cleanup,
|
||||
find_suitable_host,
|
||||
findSuitableHostForMigration,
|
||||
get_resource_type
|
||||
)
|
||||
from marvin.integration.lib.utils import cleanup_resources
|
||||
from marvin.codes import ERROR_NO_HOST_FOR_MIGRATION
|
||||
|
||||
class Services:
|
||||
"""Test memory resource limit services
|
||||
|
|
@ -248,7 +249,9 @@ class TestMemoryLimits(cloudstackTestCase):
|
|||
self.assertEqual(resource_count, expected_resource_count,
|
||||
"Resource count should match with the expected resource count")
|
||||
|
||||
host = find_suitable_host(self.apiclient, self.vm)
|
||||
host = findSuitableHostForMigration(self.apiclient, self.vm.id)
|
||||
if host is None:
|
||||
self.skipTest(ERROR_NO_HOST_FOR_MIGRATION)
|
||||
self.debug("Migrating instance: %s to host: %s" % (self.vm.name, host.name))
|
||||
try:
|
||||
self.vm.migrate(self.apiclient, host.id)
|
||||
|
|
@ -587,7 +590,9 @@ class TestDomainMemoryLimitsConfiguration(cloudstackTestCase):
|
|||
self.assertEqual(resource_count, expected_resource_count,
|
||||
"Initial resource count should with the expected resource count")
|
||||
|
||||
host = find_suitable_host(self.apiclient, vm)
|
||||
host = findSuitableHostForMigration(self.apiclient, vm.id)
|
||||
if host is None:
|
||||
self.skipTest(ERROR_NO_HOST_FOR_MIGRATION)
|
||||
self.debug("Migrating instance: %s to host: %s" %
|
||||
(vm.name, host.name))
|
||||
try:
|
||||
|
|
@ -743,7 +748,9 @@ class TestDomainMemoryLimitsConfiguration(cloudstackTestCase):
|
|||
self.assertEqual(resource_count_after_delete, expected_resource_count,
|
||||
"Resource count should match with the expected resource count")
|
||||
|
||||
host = find_suitable_host(self.apiclient, vm_2)
|
||||
host = findSuitableHostForMigration(self.apiclient, vm_2.id)
|
||||
if host is None:
|
||||
self.skipTest(ERROR_NO_HOST_FOR_MIGRATION)
|
||||
self.debug("Migrating instance: %s to host: %s" % (vm_2.name,
|
||||
host.name))
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -30,11 +30,12 @@ from marvin.integration.lib.common import (get_domain,
|
|||
get_zone,
|
||||
get_template,
|
||||
wait_for_cleanup,
|
||||
find_suitable_host,
|
||||
findSuitableHostForMigration,
|
||||
get_resource_type,
|
||||
update_resource_count
|
||||
)
|
||||
from marvin.integration.lib.utils import cleanup_resources
|
||||
from marvin.codes import ERROR_NO_HOST_FOR_MIGRATION
|
||||
|
||||
class Services:
|
||||
"""Test memory resource limit services
|
||||
|
|
@ -388,7 +389,9 @@ class TestDomainMemoryLimits(cloudstackTestCase):
|
|||
self.assertEqual(resource_count, expected_resource_count,
|
||||
"Resource count should match with the expected resource count")
|
||||
|
||||
host = find_suitable_host(self.apiclient, vm)
|
||||
host = findSuitableHostForMigration(self.apiclient, vm.id)
|
||||
if host is None:
|
||||
self.skipTest(ERROR_NO_HOST_FOR_MIGRATION)
|
||||
self.debug("Migrating instance: %s to host: %s" %
|
||||
(vm.name, host.name))
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -30,10 +30,11 @@ from marvin.integration.lib.common import (get_domain,
|
|||
get_zone,
|
||||
get_template,
|
||||
wait_for_cleanup,
|
||||
find_suitable_host,
|
||||
findSuitableHostForMigration,
|
||||
get_resource_type
|
||||
)
|
||||
from marvin.integration.lib.utils import cleanup_resources
|
||||
from marvin.codes import ERROR_NO_HOST_FOR_MIGRATION
|
||||
|
||||
class Services:
|
||||
"""Test memory resource limit services
|
||||
|
|
@ -291,7 +292,9 @@ class TestProjectsMemoryLimits(cloudstackTestCase):
|
|||
resource_count = project_list[0].memorytotal
|
||||
self.debug(resource_count)
|
||||
|
||||
host = find_suitable_host(self.apiclient, self.vm)
|
||||
host = findSuitableHostForMigration(self.apiclient, self.vm.id)
|
||||
if host is None:
|
||||
self.skipTest(ERROR_NO_HOST_FOR_MIGRATION)
|
||||
self.debug("Migrating instance: %s to host: %s" %
|
||||
(self.vm.name, host.name))
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -1254,21 +1254,10 @@ class TestRouterStopCreateFW(cloudstackTestCase):
|
|||
str(self.services["fw_rule"]["endport"]),
|
||||
"Check end port of firewall rule"
|
||||
)
|
||||
hosts = list_hosts(
|
||||
self.apiclient,
|
||||
id=router.hostid,
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(hosts, list),
|
||||
True,
|
||||
"Check for list hosts response return valid data"
|
||||
)
|
||||
host = hosts[0]
|
||||
host.user, host.passwd = get_host_credentials(self.config, host.ipaddress)
|
||||
|
||||
# For DNS and DHCP check 'dnsmasq' process status
|
||||
if self.apiclient.hypervisor.lower() == 'vmware':
|
||||
result = get_process_status(
|
||||
if (self.apiclient.hypervisor.lower() == 'vmware'
|
||||
or self.apiclient.hypervisor.lower() == 'hyperv'):
|
||||
result = get_process_status(
|
||||
self.apiclient.connection.mgtSvr,
|
||||
22,
|
||||
self.apiclient.connection.user,
|
||||
|
|
@ -1278,6 +1267,17 @@ class TestRouterStopCreateFW(cloudstackTestCase):
|
|||
hypervisor=self.apiclient.hypervisor
|
||||
)
|
||||
else:
|
||||
hosts = list_hosts(
|
||||
self.apiclient,
|
||||
id=router.hostid,
|
||||
)
|
||||
self.assertEqual(
|
||||
isinstance(hosts, list),
|
||||
True,
|
||||
"Check for list hosts response return valid data"
|
||||
)
|
||||
host = hosts[0]
|
||||
host.user, host.passwd = get_host_credentials(self.config, host.ipaddress)
|
||||
try:
|
||||
result = get_process_status(
|
||||
host.ipaddress,
|
||||
|
|
|
|||
|
|
@ -41,9 +41,10 @@ from marvin.integration.lib.common import (get_domain,
|
|||
get_free_vlan,
|
||||
wait_for_cleanup,
|
||||
list_virtual_machines,
|
||||
list_hosts)
|
||||
list_hosts,
|
||||
findSuitableHostForMigration)
|
||||
|
||||
from marvin.codes import PASS
|
||||
from marvin.codes import PASS, ERROR_NO_HOST_FOR_MIGRATION
|
||||
|
||||
import time
|
||||
|
||||
|
|
@ -715,35 +716,13 @@ class TestVMLifeCycleVPC(cloudstackTestCase):
|
|||
# works as expected.
|
||||
# 3. Make sure that we are able to access google.com from this user Vm
|
||||
|
||||
vm_list = VirtualMachine.list(self.apiclient, id=self.vm_1.id)
|
||||
self.assertEqual(validateList(vm_list)[0], PASS, "vm list validation failed, vm list is %s" % vm_list)
|
||||
|
||||
vm_hostid = vm_list[0].hostid
|
||||
|
||||
self.debug("Checking if the host is available for migration?")
|
||||
hosts = Host.list(
|
||||
self.apiclient,
|
||||
zoneid=self.zone.id,
|
||||
type='Routing'
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
isinstance(hosts, list),
|
||||
True,
|
||||
"List hosts should return a valid list"
|
||||
)
|
||||
if len(hosts) < 2:
|
||||
raise unittest.SkipTest(
|
||||
"No host available for migration. Test requires atleast 2 hosts")
|
||||
|
||||
# Remove the host of current VM from the hosts list
|
||||
hosts[:] = [host for host in hosts if host.id != vm_hostid]
|
||||
|
||||
host = hosts[0]
|
||||
|
||||
self.debug("Validating if the network rules work properly or not?")
|
||||
self.validate_network_rules()
|
||||
|
||||
host = findSuitableHostForMigration(self.apiclient, self.vm_1.id)
|
||||
if host is None:
|
||||
self.skipTest(ERROR_NO_HOST_FOR_MIGRATION)
|
||||
|
||||
self.debug("Migrating VM-ID: %s to Host: %s" % (
|
||||
self.vm_1.id,
|
||||
host.id
|
||||
|
|
@ -1506,30 +1485,13 @@ class TestVMLifeCycleSharedNwVPC(cloudstackTestCase):
|
|||
# works as expected.
|
||||
# 3. Make sure that we are able to access google.com from this user Vm
|
||||
|
||||
self.debug("Checking if the host is available for migration?")
|
||||
hosts = Host.list(
|
||||
self.apiclient,
|
||||
zoneid=self.zone.id,
|
||||
type='Routing'
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
isinstance(hosts, list),
|
||||
True,
|
||||
"List hosts should return a valid list"
|
||||
)
|
||||
if len(hosts) < 2:
|
||||
raise unittest.SkipTest(
|
||||
"No host available for migration. Test requires atleast 2 hosts")
|
||||
|
||||
# Remove the host of current VM from the hosts list
|
||||
hosts[:] = [host for host in hosts if host.id != self.vm_1.hostid]
|
||||
|
||||
host = hosts[0]
|
||||
|
||||
self.debug("Validating if network rules are coonfigured properly?")
|
||||
self.validate_network_rules()
|
||||
|
||||
host = findSuitableHostForMigration(self.apiclient, self.vm_1.id)
|
||||
if host is None:
|
||||
self.skipTest(ERROR_NO_HOST_FOR_MIGRATION)
|
||||
|
||||
self.debug("Migrating VM-ID: %s to Host: %s" % (
|
||||
self.vm_1.id,
|
||||
host.id
|
||||
|
|
@ -2559,30 +2521,13 @@ class TestVMLifeCycleStoppedVPCVR(cloudstackTestCase):
|
|||
# works as expected.
|
||||
# 3. Make sure that we are able to access google.com from this user Vm
|
||||
|
||||
self.debug("Checking if the host is available for migration?")
|
||||
hosts = Host.list(
|
||||
self.apiclient,
|
||||
zoneid=self.zone.id,
|
||||
type='Routing'
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
isinstance(hosts, list),
|
||||
True,
|
||||
"List hosts should return a valid list"
|
||||
)
|
||||
if len(hosts) < 2:
|
||||
raise unittest.SkipTest(
|
||||
"No host available for migration. Test requires atleast 2 hosts")
|
||||
|
||||
# Remove the host of current VM from the hosts list
|
||||
hosts[:] = [host for host in hosts if host.id != self.vm_1.hostid]
|
||||
|
||||
host = hosts[0]
|
||||
|
||||
self.debug("Validating if the network rules work properly or not?")
|
||||
self.validate_network_rules()
|
||||
|
||||
host = findSuitableHostForMigration(self.apiclient, self.vm_1.id)
|
||||
if host is None:
|
||||
self.skipTest(ERROR_NO_HOST_FOR_MIGRATION)
|
||||
|
||||
self.debug("Migrating VM-ID: %s on Host: %s to Host: %s" % (
|
||||
self.vm_1.id,
|
||||
self.vm_1.hostid,
|
||||
|
|
@ -3459,28 +3404,13 @@ class TestVMLifeCycleDiffHosts(cloudstackTestCase):
|
|||
# works as expected.
|
||||
# 3. Make sure that we are able to access google.com from this user Vm
|
||||
|
||||
self.debug("Checking if the host is available for migration?")
|
||||
hosts = Host.listForMigration(
|
||||
self.apiclient,
|
||||
virtualmachineid=self.vm_1.id,
|
||||
)
|
||||
self.debug("Hosts vm can be migrated to are : %s" %(hosts))
|
||||
self.assertEqual(
|
||||
isinstance(hosts, list),
|
||||
True,
|
||||
"List hosts should return a valid list"
|
||||
)
|
||||
# Remove the host of current VM from the hosts list
|
||||
hosts[:] = [host for host in hosts if host.id != self.vm_1.hostid]
|
||||
if len(hosts) <= 0:
|
||||
self.skipTest(
|
||||
"No host available for migration. Test requires atleast 2 hosts tagged with host1")
|
||||
|
||||
host = hosts[0]
|
||||
|
||||
self.debug("Validating if the network rules work properly or not?")
|
||||
self.validate_network_rules()
|
||||
|
||||
host = findSuitableHostForMigration(self.apiclient, self.vm_1.id)
|
||||
if host is None:
|
||||
self.skipTest(ERROR_NO_HOST_FOR_MIGRATION)
|
||||
|
||||
self.debug("Migrating VM-ID: %s to Host: %s" % (
|
||||
self.vm_1.id,
|
||||
host.id
|
||||
|
|
|
|||
|
|
@ -51,3 +51,4 @@ BASIC_ZONE = "basic"
|
|||
ISOLATED_NETWORK = "ISOLATED"
|
||||
SHARED_NETWORK = "SHARED"
|
||||
VPC_NETWORK = "VPC"
|
||||
ERROR_NO_HOST_FOR_MIGRATION = "Could not find suitable host for migration, please ensure setup has required no. of hosts"
|
||||
|
|
|
|||
|
|
@ -324,7 +324,8 @@ class VirtualMachine:
|
|||
domainid=None, zoneid=None, networkids=None, serviceofferingid=None,
|
||||
securitygroupids=None, projectid=None, startvm=None,
|
||||
diskofferingid=None, affinitygroupnames=None, affinitygroupids=None, group=None,
|
||||
hostid=None, keypair=None, ipaddress=None, mode='default', method='GET'):
|
||||
hostid=None, keypair=None, ipaddress=None, mode='default', method='GET',
|
||||
customcpunumber=None, customcpuspeed=None, custommemory=None):
|
||||
"""Create the instance"""
|
||||
|
||||
cmd = deployVirtualMachine.deployVirtualMachineCmd()
|
||||
|
|
@ -412,6 +413,17 @@ class VirtualMachine:
|
|||
if "userdata" in services:
|
||||
cmd.userdata = base64.urlsafe_b64encode(services["userdata"])
|
||||
|
||||
cmd.details = [{"cpuNumber": "","cpuSpeed":"","memory":""}]
|
||||
|
||||
if customcpunumber:
|
||||
cmd.details[0]["cpuNumber"] = customcpunumber
|
||||
|
||||
if customcpuspeed:
|
||||
cmd.details[0]["cpuSpeed"] = customcpuspeed
|
||||
|
||||
if custommemory:
|
||||
cmd.details[0]["memory"] = custommemory
|
||||
|
||||
if group:
|
||||
cmd.group = group
|
||||
|
||||
|
|
@ -636,6 +648,21 @@ class VirtualMachine:
|
|||
|
||||
return apiclient.updateVMAffinityGroup(cmd)
|
||||
|
||||
def scale(self, apiclient, serviceOfferingId,
|
||||
customcpunumber=None, customcpuspeed=None, custommemory=None):
|
||||
"""Change service offering of the instance"""
|
||||
cmd = scaleVirtualMachine.scaleVirtualMachineCmd()
|
||||
cmd.id = self.id
|
||||
cmd.serviceofferingid = serviceOfferingId
|
||||
cmd.details = [{"cpuNumber": "","cpuSpeed":"","memory":""}]
|
||||
if customcpunumber:
|
||||
cmd.details[0]["cpuNumber"] = customcpunumber
|
||||
if customcpuspeed:
|
||||
cmd.details[0]["cpuSpeed"] = customcpuspeed
|
||||
if custommemory:
|
||||
cmd.details[0]["memory"] = custommemory
|
||||
return apiclient.scaleVirtualMachine(cmd)
|
||||
|
||||
|
||||
class Volume:
|
||||
"""Manage Volume Life cycle
|
||||
|
|
|
|||
|
|
@ -712,18 +712,23 @@ def update_resource_count(apiclient, domainid, accountid=None,
|
|||
)
|
||||
return
|
||||
|
||||
def find_suitable_host(apiclient, vm):
|
||||
"""Returns a suitable host for VM migration"""
|
||||
def findSuitableHostForMigration(apiclient, vmid):
|
||||
"""Returns a suitable host for VM migration"""
|
||||
suitableHost = None
|
||||
try:
|
||||
hosts = Host.listForMigration(apiclient, virtualmachineid=vmid,
|
||||
)
|
||||
except Exception as e:
|
||||
raise Exception("Exception while getting hosts list suitable for migration: %s" % e)
|
||||
|
||||
hosts = Host.list(apiclient,
|
||||
virtualmachineid=vm.id,
|
||||
listall=True)
|
||||
suitablehosts = []
|
||||
if isinstance(hosts, list) and len(hosts) > 0:
|
||||
suitablehosts = [host for host in hosts if (str(host.resourcestate).lower() == "enabled"\
|
||||
and str(host.state).lower() == "up")]
|
||||
if len(suitablehosts)>0:
|
||||
suitableHost = suitablehosts[0]
|
||||
|
||||
if isinstance(hosts, list):
|
||||
assert len(hosts) > 0, "List host should return valid response"
|
||||
else:
|
||||
raise Exception("Exception: List host should return valid response")
|
||||
return hosts[0]
|
||||
return suitableHost
|
||||
|
||||
def get_resource_type(resource_id):
|
||||
"""Returns resource type"""
|
||||
|
|
@ -980,3 +985,17 @@ def verifyNetworkState(apiclient, networkid, state):
|
|||
assert validateList(networks)[0] == PASS, "Networks list validation failed, list is %s" % networks
|
||||
assert str(networks[0].state).lower() == state, "network state should be %s, it is %s" % (state, networks[0].state)
|
||||
return
|
||||
|
||||
def verifyComputeOfferingCreation(apiclient, computeofferingid):
|
||||
"""List Compute offerings by ID and verify that the offering exists"""
|
||||
|
||||
cmd = listServiceOfferings.listServiceOfferingsCmd()
|
||||
cmd.id = computeofferingid
|
||||
serviceOfferings = None
|
||||
try:
|
||||
serviceOfferings = apiclient.listServiceOfferings(cmd)
|
||||
except Exception as e:
|
||||
return FAIL
|
||||
if not (isinstance(serviceOfferings, list) and len(serviceOfferings) > 0):
|
||||
return FAIL
|
||||
return PASS
|
||||
|
|
|
|||
|
|
@ -191,7 +191,8 @@ def get_process_status(hostip, port, username, password, linklocalip, process, h
|
|||
|
||||
#SSH to the machine
|
||||
ssh = SshClient(hostip, port, username, password)
|
||||
if str(hypervisor).lower() == 'vmware':
|
||||
if (str(hypervisor).lower() == 'vmware'
|
||||
or str(hypervisor).lower() == 'hyperv'):
|
||||
ssh_command = "ssh -i /var/cloudstack/management/.ssh/id_rsa -ostricthostkeychecking=no "
|
||||
else:
|
||||
ssh_command = "ssh -i ~/.ssh/id_rsa.cloud -ostricthostkeychecking=no "
|
||||
|
|
|
|||
|
|
@ -3080,7 +3080,7 @@ div.toolbar div.button.refresh span {
|
|||
|
||||
div.toolbar div.button.add span,
|
||||
.detail-group .button.add span.icon {
|
||||
padding: 0px 0 0px 18px;
|
||||
padding: 0px 0 3px 18px;
|
||||
background: url(../images/icons.png) no-repeat -626px -209px;
|
||||
/*+placement:shift 0px 0px;*/
|
||||
position: relative;
|
||||
|
|
|
|||
Loading…
Reference in New Issue