Merge branch 'master' into resize-root

This commit is contained in:
Marcus Sorensen 2014-03-10 15:37:08 -06:00
commit 6d6e790d81
55 changed files with 797 additions and 216 deletions

View File

@ -26,7 +26,7 @@
# set environment variables
SHORTNAME="$0"
SHORTNAME="basename $0"
PIDFILE=@PIDDIR@/"$SHORTNAME".pid
LOCKFILE=@LOCKDIR@/"$SHORTNAME"
LOGFILE=@AGENTLOG@

View File

@ -26,7 +26,7 @@
# set environment variables
SHORTNAME="$0"
SHORTNAME="basename $0"
PIDFILE=@PIDDIR@/"$SHORTNAME".pid
LOCKFILE=@LOCKDIR@/"$SHORTNAME"
LOGFILE=@AGENTLOG@

View File

@ -33,7 +33,7 @@
# set environment variables
SHORTNAME="$0"
SHORTNAME="basename $0"
PIDFILE=@PIDDIR@/"$SHORTNAME".pid
LOCKFILE=@LOCKDIR@/"$SHORTNAME"
LOGFILE=@AGENTLOG@

View File

@ -26,7 +26,7 @@
# set environment variables
SHORTNAME="$0"
SHORTNAME="basename $0"
PIDFILE=@PIDDIR@/"$SHORTNAME".pid
LOCKFILE=@LOCKDIR@/"$SHORTNAME"
LOGFILE=@AGENTLOG@

View File

@ -33,7 +33,7 @@
# set environment variables
SHORTNAME="$0"
SHORTNAME="basename $0"
PIDFILE=@PIDDIR@/"$SHORTNAME".pid
LOCKFILE=@LOCKDIR@/"$SHORTNAME"
LOGFILE=@AGENTLOG@

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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) {

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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);
}
}
}

View File

@ -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";
}

View File

@ -25,7 +25,7 @@
# set environment variables
SHORTNAME="$0"
SHORTNAME="basename $0"
PIDFILE=@PIDDIR@/"$SHORTNAME".pid
LOCKFILE=@LOCKDIR@/"$SHORTNAME"
LOGFILE=@IPALOCATORLOG@

View File

@ -25,7 +25,7 @@
# set environment variables
SHORTNAME="$0"
SHORTNAME="basename $0"
PIDFILE=@PIDDIR@/"$SHORTNAME".pid
LOCKFILE=@LOCKDIR@/"$SHORTNAME"
LOGFILE=@AGENTLOG@

View File

@ -32,7 +32,7 @@
# set environment variables
SHORTNAME="$0"
SHORTNAME="basename $0"
PIDFILE=@PIDDIR@/"$SHORTNAME".pid
LOCKFILE=@LOCKDIR@/"$SHORTNAME"
LOGFILE=@AGENTLOG@

View File

@ -25,7 +25,7 @@
# set environment variables
SHORTNAME="$0"
SHORTNAME="basename $0"
PIDFILE=@PIDDIR@/"$SHORTNAME".pid
LOCKFILE=@LOCKDIR@/"$SHORTNAME"
LOGFILE=@AGENTLOG@

View File

@ -32,7 +32,7 @@
# set environment variables
SHORTNAME="$0"
SHORTNAME="basename $0"
PIDFILE=@PIDDIR@/"$SHORTNAME".pid
LOCKFILE=@LOCKDIR@/"$SHORTNAME"
LOGFILE=@AGENTLOG@

View File

@ -26,7 +26,7 @@
# set environment variables
SHORTNAME="$0"
SHORTNAME="basename $0"
PIDFILE=@PIDDIR@/"$SHORTNAME".pid
LOCKFILE=@LOCKDIR@/"$SHORTNAME"
LOGFILE=@AGENTLOG@

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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(

View File

@ -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);

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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());
}
}

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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 {

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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");

View File

@ -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';

View File

@ -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

View File

@ -26,7 +26,7 @@
# set environment variables
SHORTNAME="$0"
SHORTNAME="basename $0"
PIDFILE=@PIDDIR@/"$SHORTNAME".pid
LOCKFILE=@LOCKDIR@/"$SHORTNAME"
LOGFILE=@CPLOG@

View File

@ -26,7 +26,7 @@
# set environment variables
SHORTNAME="$0"
SHORTNAME="basename $0"
PIDFILE=@PIDDIR@/"$SHORTNAME".pid
LOCKFILE=@LOCKDIR@/"$SHORTNAME"
LOGFILE=@CPLOG@

View File

@ -26,7 +26,7 @@
# set environment variables
SHORTNAME="$0"
SHORTNAME="basename $0"
PIDFILE=@PIDDIR@/"$SHORTNAME".pid
LOCKFILE=@LOCKDIR@/"$SHORTNAME"
LOGFILE=@CPLOG@

View File

@ -27,7 +27,7 @@
# set environment variables
SHORTNAME="$0"
SHORTNAME="basename $0"
PIDFILE=@PIDDIR@/"$SHORTNAME".pid
LOCKFILE=@LOCKDIR@/"$SHORTNAME"
LOGFILE=@CPLOG@

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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

View File

@ -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:

View File

@ -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:

View File

@ -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:

View File

@ -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,

View File

@ -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

View File

@ -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"

View File

@ -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

View File

@ -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

View File

@ -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 "

View File

@ -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;