Skip to content

Commit

Permalink
Merge branch '4.7' into 4.8
Browse files Browse the repository at this point in the history
  • Loading branch information
rohityadavcloud committed May 3, 2016
2 parents d11194a + 987e800 commit 126a039
Show file tree
Hide file tree
Showing 19 changed files with 227 additions and 51 deletions.
2 changes: 1 addition & 1 deletion api/src/com/cloud/vm/VmDetailConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
public interface VmDetailConstants {
public static final String KEYBOARD = "keyboard";
public static final String NIC_ADAPTER = "nicAdapter";
public static final String ROOK_DISK_CONTROLLER = "rootDiskController";
public static final String ROOT_DISK_CONTROLLER = "rootDiskController";
public static final String NESTED_VIRTUALIZATION_FLAG = "nestedVirtualizationFlag";
public static final String HYPERVISOR_TOOLS_VERSION = "hypervisortoolsversion";
public static final String DATA_DISK_CONTROLLER = "dataDiskController";
Expand Down
2 changes: 1 addition & 1 deletion debian/control
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ Description: A common package which contains files which are shared by several C

Package: cloudstack-management
Architecture: all
Depends: ${misc:Depends}, ${python:Depends}, cloudstack-common (= ${source:Version}), tomcat6, sudo, jsvc, python-mysqldb, libmysql-java, augeas-tools, mysql-client, adduser
Depends: ${misc:Depends}, ${python:Depends}, cloudstack-common (= ${source:Version}), tomcat6, sudo, jsvc, python-mysqldb, libmysql-java, augeas-tools, mysql-client, adduser, bzip2
Conflicts: cloud-server, cloud-client, cloud-client-ui
Description: CloudStack server library
The CloudStack management server
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2909,12 +2909,12 @@ public void checkIfCanUpgrade(final VirtualMachine vmInstance, final ServiceOffe
newServiceOffering.getCpu() + " cpu(s) at " + newServiceOffering.getSpeed() + " Mhz, and " + newServiceOffering.getRamSize() + " MB of memory");
}

// Check that the service offering being upgraded to has storage tags subset of the current service offering storage tags, since volume is not migrated.
// Check that the service offering being upgraded to has all the tags of the current service offering.
final List<String> currentTags = StringUtils.csvTagsToList(currentServiceOffering.getTags());
final List<String> newTags = StringUtils.csvTagsToList(newServiceOffering.getTags());
if (!currentTags.containsAll(newTags)) {
throw new InvalidParameterValueException("Unable to upgrade virtual machine; the new service offering " + " should have tags as subset of " +
"current service offering tags. Current service offering tags: " + currentTags + "; " + "new service " + "offering tags: " + newTags);
if (!newTags.containsAll(currentTags)) {
throw new InvalidParameterValueException("Unable to upgrade virtual machine; the current service offering " + " should have tags as subset of " +
"the new service offering tags. Current service offering tags: " + currentTags + "; " + "new service " + "offering tags: " + newTags);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.ArrayList;

import com.cloud.service.dao.ServiceOfferingDao;
import junit.framework.Assert;

import org.junit.Before;
Expand Down Expand Up @@ -135,6 +137,8 @@ public class VirtualMachineManagerImplTest {
@Mock
VMInstanceDao _vmInstanceDao;
@Mock
ServiceOfferingDao _offeringDao;
@Mock
VMTemplateDao _templateDao;
@Mock
VolumeDao _volsDao;
Expand All @@ -149,6 +153,8 @@ public class VirtualMachineManagerImplTest {
@Mock
VMInstanceVO _vmInstance;
@Mock
ServiceOfferingVO _serviceOfferingMock;
@Mock
HostVO _host;
@Mock
VMTemplateVO _templateMock;
Expand Down Expand Up @@ -227,6 +233,8 @@ public void setup() {
_vmMgr._uservmDetailsDao = _vmDetailsDao;
_vmMgr._entityMgr = _entityMgr;
_vmMgr._configDepot = _configDepot;
_vmMgr._offeringDao = _offeringDao;
_vmMgr.hostAllocators = new ArrayList<>();

when(_vmMock.getId()).thenReturn(314l);
when(_vmInstance.getId()).thenReturn(1L);
Expand Down Expand Up @@ -505,4 +513,24 @@ public void testSendStopWithNullAnswer() throws Exception {

Assert.assertFalse(actual);
}

@Test
public void testCheckIfCanUpgrade() throws Exception {
when(_vmInstance.getState()).thenReturn(State.Stopped);
when(_serviceOfferingMock.isDynamic()).thenReturn(true);
when(_vmInstance.getServiceOfferingId()).thenReturn(1l);
when(_serviceOfferingMock.getId()).thenReturn(2l);

ServiceOfferingVO mockCurrentServiceOffering = mock(ServiceOfferingVO.class);

when(_offeringDao.findByIdIncludingRemoved(anyLong(), anyLong())).thenReturn(mockCurrentServiceOffering);
when(mockCurrentServiceOffering.getUseLocalStorage()).thenReturn(true);
when(_serviceOfferingMock.getUseLocalStorage()).thenReturn(true);
when(mockCurrentServiceOffering.getSystemUse()).thenReturn(true);
when(_serviceOfferingMock.getSystemUse()).thenReturn(true);
when(mockCurrentServiceOffering.getTags()).thenReturn("x,y");
when(_serviceOfferingMock.getTags()).thenReturn("z,x,y");

_vmMgr.checkIfCanUpgrade(_vmInstance, _serviceOfferingMock);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -200,10 +200,10 @@ public VirtualMachineTO implement(VirtualMachineProfile vm) {
}
}

String diskDeviceType = details.get(VmDetailConstants.ROOK_DISK_CONTROLLER);
String diskDeviceType = details.get(VmDetailConstants.ROOT_DISK_CONTROLLER);
if (userVm) {
if (diskDeviceType == null) {
details.put(VmDetailConstants.ROOK_DISK_CONTROLLER, _vmwareMgr.getRootDiskController());
details.put(VmDetailConstants.ROOT_DISK_CONTROLLER, _vmwareMgr.getRootDiskController());
}
}
String diskController = details.get(VmDetailConstants.DATA_DISK_CONTROLLER);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,7 +236,7 @@
import com.cloud.hypervisor.vmware.mo.NetworkDetails;
import com.cloud.hypervisor.vmware.mo.TaskMO;
import com.cloud.hypervisor.vmware.mo.VirtualEthernetCardType;
import com.cloud.hypervisor.vmware.mo.VirtualMachineDiskInfo;
import org.apache.cloudstack.utils.volume.VirtualMachineDiskInfo;
import com.cloud.hypervisor.vmware.mo.VirtualMachineDiskInfoBuilder;
import com.cloud.hypervisor.vmware.mo.VirtualMachineMO;
import com.cloud.hypervisor.vmware.mo.VirtualSwitchType;
Expand Down Expand Up @@ -1412,7 +1412,7 @@ protected StartAnswer execute(StartCommand cmd) {
String vmInternalCSName = names.first();
String vmNameOnVcenter = names.second();
String dataDiskController = vmSpec.getDetails().get(VmDetailConstants.DATA_DISK_CONTROLLER);
String rootDiskController = vmSpec.getDetails().get(VmDetailConstants.ROOK_DISK_CONTROLLER);
String rootDiskController = vmSpec.getDetails().get(VmDetailConstants.ROOT_DISK_CONTROLLER);

// If root disk controller is scsi, then data disk controller would also be scsi instead of using 'osdefault'
// This helps avoid mix of different scsi subtype controllers in instance.
Expand Down Expand Up @@ -1451,7 +1451,7 @@ protected StartAnswer execute(StartCommand cmd) {
s_logger.error(msg);
throw new Exception(msg);
}

String guestOsId = translateGuestOsIdentifier(vmSpec.getArch(), vmSpec.getOs(), vmSpec.getPlatformEmulator()).value();
DiskTO[] disks = validateDisks(vmSpec.getDisks());
assert (disks.length > 0);
NicTO[] nics = vmSpec.getNics();
Expand Down Expand Up @@ -1564,7 +1564,7 @@ protected StartAnswer execute(StartCommand cmd) {
tearDownVm(vmMo);
}else if (!hyperHost.createBlankVm(vmNameOnVcenter, vmInternalCSName, vmSpec.getCpus(), vmSpec.getMaxSpeed().intValue(),
getReservedCpuMHZ(vmSpec), vmSpec.getLimitCpuUse(), (int)(vmSpec.getMaxRam() / (1024 * 1024)), getReservedMemoryMb(vmSpec),
translateGuestOsIdentifier(vmSpec.getArch(), vmSpec.getOs(), vmSpec.getPlatformEmulator()).value(), rootDiskDataStoreDetails.first(), false, controllerInfo, systemVm)) {
guestOsId, rootDiskDataStoreDetails.first(), false, controllerInfo, systemVm)) {
throw new Exception("Failed to create VM. vmName: " + vmInternalCSName);
}
}
Expand All @@ -1588,7 +1588,6 @@ protected StartAnswer execute(StartCommand cmd) {
}

VirtualMachineConfigSpec vmConfigSpec = new VirtualMachineConfigSpec();
String guestOsId = translateGuestOsIdentifier(vmSpec.getArch(), vmSpec.getOs(), vmSpec.getPlatformEmulator()).value();

VmwareHelper.setBasicVmConfig(vmConfigSpec, vmSpec.getCpus(), vmSpec.getMaxSpeed(),
getReservedCpuMHZ(vmSpec), (int)(vmSpec.getMaxRam() / (1024 * 1024)), getReservedMemoryMb(vmSpec),
Expand Down Expand Up @@ -2322,14 +2321,14 @@ private int getDiskController(VirtualMachineDiskInfo matchingExistingDisk, DiskT

if (vol.getType() == Volume.Type.ROOT) {
Map<String, String> vmDetails = vmSpec.getDetails();
if (vmDetails != null && vmDetails.get(VmDetailConstants.ROOK_DISK_CONTROLLER) != null) {
if (vmDetails.get(VmDetailConstants.ROOK_DISK_CONTROLLER).equalsIgnoreCase("scsi")) {
if (vmDetails != null && vmDetails.get(VmDetailConstants.ROOT_DISK_CONTROLLER) != null) {
if (vmDetails.get(VmDetailConstants.ROOT_DISK_CONTROLLER).equalsIgnoreCase("scsi")) {
s_logger.info("Chose disk controller for vol " + vol.getType() + " -> scsi, based on root disk controller settings: " +
vmDetails.get(VmDetailConstants.ROOK_DISK_CONTROLLER));
vmDetails.get(VmDetailConstants.ROOT_DISK_CONTROLLER));
controllerKey = scsiControllerKey;
} else {
s_logger.info("Chose disk controller for vol " + vol.getType() + " -> ide, based on root disk controller settings: " +
vmDetails.get(VmDetailConstants.ROOK_DISK_CONTROLLER));
vmDetails.get(VmDetailConstants.ROOT_DISK_CONTROLLER));
controllerKey = ideControllerKey;
}
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import com.google.common.base.Strings;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

Expand Down Expand Up @@ -88,7 +89,7 @@
import com.cloud.hypervisor.vmware.mo.HostStorageSystemMO;
import com.cloud.hypervisor.vmware.mo.HypervisorHostHelper;
import com.cloud.hypervisor.vmware.mo.NetworkDetails;
import com.cloud.hypervisor.vmware.mo.VirtualMachineDiskInfo;
import org.apache.cloudstack.utils.volume.VirtualMachineDiskInfo;
import com.cloud.hypervisor.vmware.mo.VirtualMachineMO;
import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost;
import com.cloud.hypervisor.vmware.resource.VmwareResource;
Expand Down Expand Up @@ -1363,24 +1364,15 @@ private Answer attachVolume(Command cmd, DiskTO disk, boolean isAttach, boolean
AttachAnswer answer = new AttachAnswer(disk);

if (isAttach) {
String dataDiskController = controllerInfo.get(VmDetailConstants.DATA_DISK_CONTROLLER);
String rootDiskController = controllerInfo.get(VmDetailConstants.ROOK_DISK_CONTROLLER);
DiskControllerType rootDiskControllerType = DiskControllerType.getType(rootDiskController);

if (dataDiskController == null) {
dataDiskController = getLegacyVmDataDiskController();
} else if ((rootDiskControllerType == DiskControllerType.lsilogic) ||
(rootDiskControllerType == DiskControllerType.lsisas1068) ||
(rootDiskControllerType == DiskControllerType.pvscsi) ||
(rootDiskControllerType == DiskControllerType.buslogic)) {
//TODO: Support mix of SCSI controller types for single VM. If root disk is already over
//a SCSI controller then use the same for data volume as well. This limitation will go once mix
//of SCSI controller types for single VM.
dataDiskController = rootDiskController;
} else if (DiskControllerType.getType(dataDiskController) == DiskControllerType.osdefault) {
dataDiskController = vmMo.getRecommendedDiskController(null);
String diskController = getLegacyVmDataDiskController();
if (controllerInfo != null &&
!Strings.isNullOrEmpty(controllerInfo.get(VmDetailConstants.DATA_DISK_CONTROLLER))) {
diskController = controllerInfo.get(VmDetailConstants.DATA_DISK_CONTROLLER);
}
vmMo.attachDisk(new String[] {datastoreVolumePath}, morDs, dataDiskController);
if (DiskControllerType.getType(diskController) == DiskControllerType.osdefault) {
diskController = vmMo.getRecommendedDiskController(null);
}
vmMo.attachDisk(new String[] {datastoreVolumePath}, morDs, diskController);
} else {
vmMo.removeAllSnapshots();
vmMo.detachDisk(datastoreVolumePath, false);
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@
<cs.servlet.version>2.5</cs.servlet.version>
<cs.jstl.version>1.2</cs.jstl.version>
<cs.selenium.server.version>1.0-20081010.060147</cs.selenium.server.version>
<cs.vmware.api.version>5.5</cs.vmware.api.version>
<cs.vmware.api.version>6.0</cs.vmware.api.version>
<org.springframework.version>3.2.12.RELEASE</org.springframework.version>
<cs.mockito.version>1.9.5</cs.mockito.version>
<cs.powermock.version>1.5.3</cs.powermock.version>
Expand Down
6 changes: 3 additions & 3 deletions server/src/com/cloud/api/query/QueryManagerImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -2620,11 +2620,11 @@ private List<ServiceOfferingJoinVO> filterOfferingsOnCurrentTags(List<ServiceOff
if(currentVmOffering == null) return offerings;
List<String> currentTagsList = StringUtils.csvTagsToList(currentVmOffering.getTags());

// New offerings should be a subset of existing storage tags. Discard offerings who are not.
// New service offering should have all the tags of the current service offering.
List<ServiceOfferingJoinVO> filteredOfferings = new ArrayList<>();
for (ServiceOfferingJoinVO offering : offerings){
List<String> tags = StringUtils.csvTagsToList(offering.getTags());
if(currentTagsList.containsAll(tags)){
List<String> newTagsList = StringUtils.csvTagsToList(offering.getTags());
if(newTagsList.containsAll(currentTagsList)){
filteredOfferings.add(offering);
}
}
Expand Down
36 changes: 35 additions & 1 deletion server/src/com/cloud/storage/VolumeApiServiceImpl.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,18 @@

import com.cloud.utils.EncryptionUtil;
import com.cloud.utils.db.TransactionCallbackWithException;
import com.google.common.base.Strings;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonParseException;

import org.apache.cloudstack.api.command.user.volume.GetUploadParamsForVolumeCmd;
import org.apache.cloudstack.api.response.GetUploadParamsResponse;
import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
import org.apache.cloudstack.storage.command.TemplateOrVolumePostUploadCommand;
import org.apache.cloudstack.utils.imagestore.ImageStoreUtil;
import org.apache.cloudstack.utils.volume.VirtualMachineDiskInfo;
import org.apache.log4j.Logger;
import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd;
Expand Down Expand Up @@ -112,12 +115,14 @@
import com.cloud.hypervisor.HypervisorCapabilitiesVO;
import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
import com.cloud.org.Grouping;
import com.cloud.serializer.GsonHelper;
import com.cloud.service.dao.ServiceOfferingDetailsDao;
import com.cloud.storage.Storage.ImageFormat;
import com.cloud.storage.dao.DiskOfferingDao;
import com.cloud.storage.dao.SnapshotDao;
import com.cloud.storage.dao.VMTemplateDao;
import com.cloud.storage.dao.VolumeDao;
import com.cloud.storage.dao.VolumeDetailsDao;
import com.cloud.storage.snapshot.SnapshotApiService;
import com.cloud.storage.snapshot.SnapshotManager;
import com.cloud.template.TemplateManager;
Expand Down Expand Up @@ -146,6 +151,7 @@
import com.cloud.utils.exception.CloudRuntimeException;
import com.cloud.utils.fsm.NoTransitionException;
import com.cloud.utils.fsm.StateMachine2;
import com.cloud.vm.UserVmManager;
import com.cloud.vm.UserVmVO;
import com.cloud.vm.VMInstanceVO;
import com.cloud.vm.VirtualMachine;
Expand Down Expand Up @@ -191,6 +197,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
@Inject
VolumeDao _volsDao;
@Inject
VolumeDetailsDao _volDetailDao;
@Inject
HostDao _hostDao;
@Inject
SnapshotDao _snapshotDao;
Expand Down Expand Up @@ -240,6 +248,9 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
VmWorkJobDao _workJobDao;
@Inject
ClusterDetailsDao _clusterDetailsDao;
@Inject
UserVmManager _userVmMgr;
protected Gson _gson;

private List<StoragePoolAllocator> _storagePoolAllocators;

Expand All @@ -253,6 +264,7 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic

protected VolumeApiServiceImpl() {
_volStateMachine = Volume.State.getStateMachine();
_gson = GsonHelper.getGsonLogger();
}

/*
Expand Down Expand Up @@ -1835,6 +1847,26 @@ private Volume orchestrateDetachVolumeFromVM(long vmId, long volumeId) {
}
}

public void updateMissingRootDiskController(final VMInstanceVO vm, final String rootVolChainInfo) {
if (vm == null || !VirtualMachine.Type.User.equals(vm.getType()) || Strings.isNullOrEmpty(rootVolChainInfo)) {
return;
}
String rootDiskController = null;
try {
final VirtualMachineDiskInfo infoInChain = _gson.fromJson(rootVolChainInfo, VirtualMachineDiskInfo.class);
if (infoInChain != null) {
rootDiskController = infoInChain.getControllerFromDeviceBusName();
}
final UserVmVO userVmVo = _userVmDao.findById(vm.getId());
if ((rootDiskController != null) && (!rootDiskController.isEmpty())) {
_userVmDao.loadDetails(userVmVo);
_userVmMgr.persistDeviceBusInfo(userVmVo, rootDiskController);
}
} catch (JsonParseException e) {
s_logger.debug("Error parsing chain info json: " + e.getMessage());
}
}

@DB
@Override
@ActionEvent(eventType = EventTypes.EVENT_VOLUME_MIGRATE, eventDescription = "migrating volume", async = true)
Expand Down Expand Up @@ -1924,6 +1956,7 @@ public Volume migrateVolume(MigrateVolumeCmd cmd) {
throw new InvalidParameterValueException("Cannot migrate ROOT volume of a stopped VM to a storage pool in a different VMware datacenter");
}
}
updateMissingRootDiskController(vm, vol.getChainInfo());
}
}
}
Expand Down Expand Up @@ -2472,9 +2505,10 @@ private VolumeVO sendAttachVolumeCommand(UserVmVO vm, VolumeVO volumeToAttach, L
}
_userVmDao.loadDetails(vm);
Map<String, String> controllerInfo = new HashMap<String, String>();
controllerInfo.put(VmDetailConstants.ROOK_DISK_CONTROLLER, vm.getDetail(VmDetailConstants.ROOK_DISK_CONTROLLER));
controllerInfo.put(VmDetailConstants.ROOT_DISK_CONTROLLER, vm.getDetail(VmDetailConstants.ROOT_DISK_CONTROLLER));
controllerInfo.put(VmDetailConstants.DATA_DISK_CONTROLLER, vm.getDetail(VmDetailConstants.DATA_DISK_CONTROLLER));
cmd.setControllerInfo(controllerInfo);
s_logger.debug("Attach volume id:" + volumeToAttach.getId() + " on VM id:" + vm.getId() + " has controller info:" + controllerInfo);

try {
answer = (AttachAnswer)_agentMgr.send(hostId, cmd);
Expand Down
2 changes: 2 additions & 0 deletions server/src/com/cloud/vm/UserVmManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,6 @@ UserVm updateVirtualMachine(long id, String displayName, String group, Boolean h
public void removeCustomOfferingDetails(long vmId);

void generateUsageEvent(VirtualMachine vm, boolean isDisplay, String eventType);

void persistDeviceBusInfo(UserVmVO paramUserVmVO, String paramString);
}
Loading

0 comments on commit 126a039

Please sign in to comment.