Skip to content

Commit 4d57ec0

Browse files
committed
Merge branch '4.8'
Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
2 parents e762e27 + 126a039 commit 4d57ec0

16 files changed

Lines changed: 214 additions & 38 deletions

File tree

debian/control

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ Description: A common package which contains files which are shared by several C
1515

1616
Package: cloudstack-management
1717
Architecture: all
18-
Depends: ${misc:Depends}, ${python:Depends}, cloudstack-common (= ${source:Version}), tomcat6, sudo, jsvc, python-mysqldb, libmysql-java, augeas-tools, mysql-client, adduser
18+
Depends: ${misc:Depends}, ${python:Depends}, cloudstack-common (= ${source:Version}), tomcat6, sudo, jsvc, python-mysqldb, libmysql-java, augeas-tools, mysql-client, adduser, bzip2
1919
Conflicts: cloud-server, cloud-client, cloud-client-ui
2020
Description: CloudStack server library
2121
The CloudStack management server

engine/orchestration/src/com/cloud/vm/VirtualMachineManagerImpl.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2909,12 +2909,12 @@ public void checkIfCanUpgrade(final VirtualMachine vmInstance, final ServiceOffe
29092909
newServiceOffering.getCpu() + " cpu(s) at " + newServiceOffering.getSpeed() + " Mhz, and " + newServiceOffering.getRamSize() + " MB of memory");
29102910
}
29112911

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

engine/orchestration/test/com/cloud/vm/VirtualMachineManagerImplTest.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,9 @@
3030
import java.util.Iterator;
3131
import java.util.List;
3232
import java.util.Map;
33+
import java.util.ArrayList;
3334

35+
import com.cloud.service.dao.ServiceOfferingDao;
3436
import junit.framework.Assert;
3537

3638
import org.junit.Before;
@@ -136,6 +138,8 @@ public class VirtualMachineManagerImplTest {
136138
@Mock
137139
VMInstanceDao _vmInstanceDao;
138140
@Mock
141+
ServiceOfferingDao _offeringDao;
142+
@Mock
139143
VMTemplateDao _templateDao;
140144
@Mock
141145
VolumeDao _volsDao;
@@ -150,6 +154,8 @@ public class VirtualMachineManagerImplTest {
150154
@Mock
151155
VMInstanceVO _vmInstance;
152156
@Mock
157+
ServiceOfferingVO _serviceOfferingMock;
158+
@Mock
153159
HostVO _host;
154160
@Mock
155161
VMTemplateVO _templateMock;
@@ -228,6 +234,8 @@ public void setup() {
228234
_vmMgr._uservmDetailsDao = _vmDetailsDao;
229235
_vmMgr._entityMgr = _entityMgr;
230236
_vmMgr._configDepot = _configDepot;
237+
_vmMgr._offeringDao = _offeringDao;
238+
_vmMgr.hostAllocators = new ArrayList<>();
231239

232240
when(_vmMock.getId()).thenReturn(314l);
233241
when(_vmInstance.getId()).thenReturn(1L);
@@ -514,4 +522,24 @@ public void testExeceuteInSequence() {
514522
assertTrue(_vmMgr.getExecuteInSequence(HypervisorType.VMware) == HypervisorGuru.VmwareFullClone.value());
515523
assertTrue(_vmMgr.getExecuteInSequence(HypervisorType.Ovm3) == VirtualMachineManager.ExecuteInSequence.value());
516524
}
525+
526+
@Test
527+
public void testCheckIfCanUpgrade() throws Exception {
528+
when(_vmInstance.getState()).thenReturn(State.Stopped);
529+
when(_serviceOfferingMock.isDynamic()).thenReturn(true);
530+
when(_vmInstance.getServiceOfferingId()).thenReturn(1l);
531+
when(_serviceOfferingMock.getId()).thenReturn(2l);
532+
533+
ServiceOfferingVO mockCurrentServiceOffering = mock(ServiceOfferingVO.class);
534+
535+
when(_offeringDao.findByIdIncludingRemoved(anyLong(), anyLong())).thenReturn(mockCurrentServiceOffering);
536+
when(mockCurrentServiceOffering.getUseLocalStorage()).thenReturn(true);
537+
when(_serviceOfferingMock.getUseLocalStorage()).thenReturn(true);
538+
when(mockCurrentServiceOffering.getSystemUse()).thenReturn(true);
539+
when(_serviceOfferingMock.getSystemUse()).thenReturn(true);
540+
when(mockCurrentServiceOffering.getTags()).thenReturn("x,y");
541+
when(_serviceOfferingMock.getTags()).thenReturn("z,x,y");
542+
543+
_vmMgr.checkIfCanUpgrade(_vmInstance, _serviceOfferingMock);
544+
}
517545
}

plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@
237237
import com.cloud.hypervisor.vmware.mo.NetworkDetails;
238238
import com.cloud.hypervisor.vmware.mo.TaskMO;
239239
import com.cloud.hypervisor.vmware.mo.VirtualEthernetCardType;
240-
import com.cloud.hypervisor.vmware.mo.VirtualMachineDiskInfo;
240+
import org.apache.cloudstack.utils.volume.VirtualMachineDiskInfo;
241241
import com.cloud.hypervisor.vmware.mo.VirtualMachineDiskInfoBuilder;
242242
import com.cloud.hypervisor.vmware.mo.VirtualMachineMO;
243243
import com.cloud.hypervisor.vmware.mo.VirtualSwitchType;
@@ -1452,7 +1452,7 @@ protected StartAnswer execute(StartCommand cmd) {
14521452
s_logger.error(msg);
14531453
throw new Exception(msg);
14541454
}
1455-
1455+
String guestOsId = translateGuestOsIdentifier(vmSpec.getArch(), vmSpec.getOs(), vmSpec.getPlatformEmulator()).value();
14561456
DiskTO[] disks = validateDisks(vmSpec.getDisks());
14571457
assert (disks.length > 0);
14581458
NicTO[] nics = vmSpec.getNics();
@@ -1565,7 +1565,7 @@ protected StartAnswer execute(StartCommand cmd) {
15651565
tearDownVm(vmMo);
15661566
}else if (!hyperHost.createBlankVm(vmNameOnVcenter, vmInternalCSName, vmSpec.getCpus(), vmSpec.getMaxSpeed().intValue(),
15671567
getReservedCpuMHZ(vmSpec), vmSpec.getLimitCpuUse(), (int)(vmSpec.getMaxRam() / (1024 * 1024)), getReservedMemoryMb(vmSpec),
1568-
translateGuestOsIdentifier(vmSpec.getArch(), vmSpec.getOs(), vmSpec.getPlatformEmulator()).value(), rootDiskDataStoreDetails.first(), false, controllerInfo, systemVm)) {
1568+
guestOsId, rootDiskDataStoreDetails.first(), false, controllerInfo, systemVm)) {
15691569
throw new Exception("Failed to create VM. vmName: " + vmInternalCSName);
15701570
}
15711571
}
@@ -1589,7 +1589,6 @@ protected StartAnswer execute(StartCommand cmd) {
15891589
}
15901590

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

15941593
VmwareHelper.setBasicVmConfig(vmConfigSpec, vmSpec.getCpus(), vmSpec.getMaxSpeed(),
15951594
getReservedCpuMHZ(vmSpec), (int)(vmSpec.getMaxRam() / (1024 * 1024)), getReservedMemoryMb(vmSpec),

plugins/hypervisors/vmware/src/com/cloud/storage/resource/VmwareStorageProcessor.java

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import java.util.concurrent.Executors;
3434
import java.util.concurrent.TimeUnit;
3535

36+
import com.google.common.base.Strings;
3637
import org.apache.commons.lang.StringUtils;
3738
import org.apache.log4j.Logger;
3839

@@ -88,7 +89,7 @@
8889
import com.cloud.hypervisor.vmware.mo.HostStorageSystemMO;
8990
import com.cloud.hypervisor.vmware.mo.HypervisorHostHelper;
9091
import com.cloud.hypervisor.vmware.mo.NetworkDetails;
91-
import com.cloud.hypervisor.vmware.mo.VirtualMachineDiskInfo;
92+
import org.apache.cloudstack.utils.volume.VirtualMachineDiskInfo;
9293
import com.cloud.hypervisor.vmware.mo.VirtualMachineMO;
9394
import com.cloud.hypervisor.vmware.mo.VmwareHypervisorHost;
9495
import com.cloud.hypervisor.vmware.resource.VmwareResource;
@@ -1366,24 +1367,15 @@ private Answer attachVolume(Command cmd, DiskTO disk, boolean isAttach, boolean
13661367
AttachAnswer answer = new AttachAnswer(disk);
13671368

13681369
if (isAttach) {
1369-
String dataDiskController = controllerInfo.get(VmDetailConstants.DATA_DISK_CONTROLLER);
1370-
String rootDiskController = controllerInfo.get(VmDetailConstants.ROOT_DISK_CONTROLLER);
1371-
DiskControllerType rootDiskControllerType = DiskControllerType.getType(rootDiskController);
1372-
1373-
if (dataDiskController == null) {
1374-
dataDiskController = getLegacyVmDataDiskController();
1375-
} else if ((rootDiskControllerType == DiskControllerType.lsilogic) ||
1376-
(rootDiskControllerType == DiskControllerType.lsisas1068) ||
1377-
(rootDiskControllerType == DiskControllerType.pvscsi) ||
1378-
(rootDiskControllerType == DiskControllerType.buslogic)) {
1379-
//TODO: Support mix of SCSI controller types for single VM. If root disk is already over
1380-
//a SCSI controller then use the same for data volume as well. This limitation will go once mix
1381-
//of SCSI controller types for single VM.
1382-
dataDiskController = rootDiskController;
1383-
} else if (DiskControllerType.getType(dataDiskController) == DiskControllerType.osdefault) {
1384-
dataDiskController = vmMo.getRecommendedDiskController(null);
1370+
String diskController = getLegacyVmDataDiskController();
1371+
if (controllerInfo != null &&
1372+
!Strings.isNullOrEmpty(controllerInfo.get(VmDetailConstants.DATA_DISK_CONTROLLER))) {
1373+
diskController = controllerInfo.get(VmDetailConstants.DATA_DISK_CONTROLLER);
13851374
}
1386-
vmMo.attachDisk(new String[] {datastoreVolumePath}, morDs, dataDiskController);
1375+
if (DiskControllerType.getType(diskController) == DiskControllerType.osdefault) {
1376+
diskController = vmMo.getRecommendedDiskController(null);
1377+
}
1378+
vmMo.attachDisk(new String[] {datastoreVolumePath}, morDs, diskController);
13871379
} else {
13881380
vmMo.removeAllSnapshots();
13891381
vmMo.detachDisk(datastoreVolumePath, false);

server/src/com/cloud/api/query/QueryManagerImpl.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2620,11 +2620,11 @@ private List<ServiceOfferingJoinVO> filterOfferingsOnCurrentTags(List<ServiceOff
26202620
if(currentVmOffering == null) return offerings;
26212621
List<String> currentTagsList = StringUtils.csvTagsToList(currentVmOffering.getTags());
26222622

2623-
// New offerings should be a subset of existing storage tags. Discard offerings who are not.
2623+
// New service offering should have all the tags of the current service offering.
26242624
List<ServiceOfferingJoinVO> filteredOfferings = new ArrayList<>();
26252625
for (ServiceOfferingJoinVO offering : offerings){
2626-
List<String> tags = StringUtils.csvTagsToList(offering.getTags());
2627-
if(currentTagsList.containsAll(tags)){
2626+
List<String> newTagsList = StringUtils.csvTagsToList(offering.getTags());
2627+
if(newTagsList.containsAll(currentTagsList)){
26282628
filteredOfferings.add(offering);
26292629
}
26302630
}

server/src/com/cloud/storage/VolumeApiServiceImpl.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,15 +30,18 @@
3030

3131
import com.cloud.utils.EncryptionUtil;
3232
import com.cloud.utils.db.TransactionCallbackWithException;
33+
import com.google.common.base.Strings;
3334
import com.google.gson.Gson;
3435
import com.google.gson.GsonBuilder;
36+
import com.google.gson.JsonParseException;
3537

3638
import org.apache.cloudstack.api.command.user.volume.GetUploadParamsForVolumeCmd;
3739
import org.apache.cloudstack.api.response.GetUploadParamsResponse;
3840
import org.apache.cloudstack.engine.subsystem.api.storage.DataObject;
3941
import org.apache.cloudstack.engine.subsystem.api.storage.EndPoint;
4042
import org.apache.cloudstack.storage.command.TemplateOrVolumePostUploadCommand;
4143
import org.apache.cloudstack.utils.imagestore.ImageStoreUtil;
44+
import org.apache.cloudstack.utils.volume.VirtualMachineDiskInfo;
4245
import org.apache.log4j.Logger;
4346
import org.apache.cloudstack.api.command.user.volume.AttachVolumeCmd;
4447
import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd;
@@ -112,12 +115,14 @@
112115
import com.cloud.hypervisor.HypervisorCapabilitiesVO;
113116
import com.cloud.hypervisor.dao.HypervisorCapabilitiesDao;
114117
import com.cloud.org.Grouping;
118+
import com.cloud.serializer.GsonHelper;
115119
import com.cloud.service.dao.ServiceOfferingDetailsDao;
116120
import com.cloud.storage.Storage.ImageFormat;
117121
import com.cloud.storage.dao.DiskOfferingDao;
118122
import com.cloud.storage.dao.SnapshotDao;
119123
import com.cloud.storage.dao.VMTemplateDao;
120124
import com.cloud.storage.dao.VolumeDao;
125+
import com.cloud.storage.dao.VolumeDetailsDao;
121126
import com.cloud.storage.snapshot.SnapshotApiService;
122127
import com.cloud.storage.snapshot.SnapshotManager;
123128
import com.cloud.template.TemplateManager;
@@ -146,6 +151,7 @@
146151
import com.cloud.utils.exception.CloudRuntimeException;
147152
import com.cloud.utils.fsm.NoTransitionException;
148153
import com.cloud.utils.fsm.StateMachine2;
154+
import com.cloud.vm.UserVmManager;
149155
import com.cloud.vm.UserVmVO;
150156
import com.cloud.vm.VMInstanceVO;
151157
import com.cloud.vm.VirtualMachine;
@@ -191,6 +197,8 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
191197
@Inject
192198
VolumeDao _volsDao;
193199
@Inject
200+
VolumeDetailsDao _volDetailDao;
201+
@Inject
194202
HostDao _hostDao;
195203
@Inject
196204
SnapshotDao _snapshotDao;
@@ -240,6 +248,9 @@ public class VolumeApiServiceImpl extends ManagerBase implements VolumeApiServic
240248
VmWorkJobDao _workJobDao;
241249
@Inject
242250
ClusterDetailsDao _clusterDetailsDao;
251+
@Inject
252+
UserVmManager _userVmMgr;
253+
protected Gson _gson;
243254

244255
private List<StoragePoolAllocator> _storagePoolAllocators;
245256

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

254265
protected VolumeApiServiceImpl() {
255266
_volStateMachine = Volume.State.getStateMachine();
267+
_gson = GsonHelper.getGsonLogger();
256268
}
257269

258270
/*
@@ -1835,6 +1847,26 @@ private Volume orchestrateDetachVolumeFromVM(long vmId, long volumeId) {
18351847
}
18361848
}
18371849

1850+
public void updateMissingRootDiskController(final VMInstanceVO vm, final String rootVolChainInfo) {
1851+
if (vm == null || !VirtualMachine.Type.User.equals(vm.getType()) || Strings.isNullOrEmpty(rootVolChainInfo)) {
1852+
return;
1853+
}
1854+
String rootDiskController = null;
1855+
try {
1856+
final VirtualMachineDiskInfo infoInChain = _gson.fromJson(rootVolChainInfo, VirtualMachineDiskInfo.class);
1857+
if (infoInChain != null) {
1858+
rootDiskController = infoInChain.getControllerFromDeviceBusName();
1859+
}
1860+
final UserVmVO userVmVo = _userVmDao.findById(vm.getId());
1861+
if ((rootDiskController != null) && (!rootDiskController.isEmpty())) {
1862+
_userVmDao.loadDetails(userVmVo);
1863+
_userVmMgr.persistDeviceBusInfo(userVmVo, rootDiskController);
1864+
}
1865+
} catch (JsonParseException e) {
1866+
s_logger.debug("Error parsing chain info json: " + e.getMessage());
1867+
}
1868+
}
1869+
18381870
@DB
18391871
@Override
18401872
@ActionEvent(eventType = EventTypes.EVENT_VOLUME_MIGRATE, eventDescription = "migrating volume", async = true)
@@ -1924,6 +1956,7 @@ public Volume migrateVolume(MigrateVolumeCmd cmd) {
19241956
throw new InvalidParameterValueException("Cannot migrate ROOT volume of a stopped VM to a storage pool in a different VMware datacenter");
19251957
}
19261958
}
1959+
updateMissingRootDiskController(vm, vol.getChainInfo());
19271960
}
19281961
}
19291962
}
@@ -2475,6 +2508,7 @@ private VolumeVO sendAttachVolumeCommand(UserVmVO vm, VolumeVO volumeToAttach, L
24752508
controllerInfo.put(VmDetailConstants.ROOT_DISK_CONTROLLER, vm.getDetail(VmDetailConstants.ROOT_DISK_CONTROLLER));
24762509
controllerInfo.put(VmDetailConstants.DATA_DISK_CONTROLLER, vm.getDetail(VmDetailConstants.DATA_DISK_CONTROLLER));
24772510
cmd.setControllerInfo(controllerInfo);
2511+
s_logger.debug("Attach volume id:" + volumeToAttach.getId() + " on VM id:" + vm.getId() + " has controller info:" + controllerInfo);
24782512

24792513
try {
24802514
answer = (AttachAnswer)_agentMgr.send(hostId, cmd);

server/src/com/cloud/vm/UserVmManager.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,4 +114,6 @@ UserVm updateVirtualMachine(long id, String displayName, String group, Boolean h
114114
public void removeCustomOfferingDetails(long vmId);
115115

116116
void generateUsageEvent(VirtualMachine vm, boolean isDisplay, String eventType);
117+
118+
void persistDeviceBusInfo(UserVmVO paramUserVmVO, String paramString);
117119
}

server/src/com/cloud/vm/UserVmManagerImpl.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@
8989
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreDao;
9090
import org.apache.cloudstack.storage.datastore.db.TemplateDataStoreVO;
9191
import org.apache.commons.codec.binary.Base64;
92+
import org.apache.commons.lang.StringUtils;
9293
import org.apache.log4j.Logger;
9394

9495
import com.cloud.agent.AgentManager;
@@ -5452,6 +5453,17 @@ private void encryptAndStorePassword(UserVmVO vm, String password) {
54525453
}
54535454
}
54545455

5456+
public void persistDeviceBusInfo(UserVmVO vm, String rootDiskController) {
5457+
String existingVmRootDiskController = vm.getDetail(VmDetailConstants.ROOT_DISK_CONTROLLER);
5458+
if (StringUtils.isEmpty(existingVmRootDiskController) && !StringUtils.isEmpty(rootDiskController)) {
5459+
vm.setDetail(VmDetailConstants.ROOT_DISK_CONTROLLER, rootDiskController);
5460+
_vmDao.saveDetails(vm);
5461+
if (s_logger.isDebugEnabled()) {
5462+
s_logger.debug("Persisted device bus information rootDiskController=" + rootDiskController + " for vm: " + vm.getDisplayName());
5463+
}
5464+
}
5465+
}
5466+
54555467
@Override
54565468
public String getConfigComponentName() {
54575469
return UserVmManager.class.getSimpleName();

server/test/com/cloud/storage/VolumeApiServiceImplTest.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@
1818

1919
import static org.mockito.Matchers.any;
2020
import static org.mockito.Matchers.anyLong;
21+
import static org.mockito.Matchers.anyString;
22+
import static org.mockito.Matchers.eq;
2123
import static org.mockito.Mockito.doNothing;
24+
import static org.mockito.Mockito.times;
25+
import static org.mockito.Mockito.verify;
2226
import static org.mockito.Mockito.when;
2327

2428
import java.lang.reflect.Field;
@@ -28,7 +32,10 @@
2832

2933
import javax.inject.Inject;
3034

35+
import com.cloud.serializer.GsonHelper;
3136
import com.cloud.user.User;
37+
import com.cloud.vm.UserVmManager;
38+
import com.cloud.vm.VirtualMachine;
3239
import junit.framework.Assert;
3340
import org.apache.cloudstack.api.command.user.volume.CreateVolumeCmd;
3441
import org.junit.After;
@@ -101,6 +108,8 @@ public class VolumeApiServiceImplTest {
101108
VolumeService volService;
102109
@Mock
103110
CreateVolumeCmd createVol;
111+
@Mock
112+
UserVmManager _userVmMgr;
104113

105114
DetachVolumeCmd detachCmd = new DetachVolumeCmd();
106115
Class<?> _detachCmdClass = detachCmd.getClass();
@@ -118,6 +127,8 @@ public void setup() throws Exception {
118127
_svc._jobMgr = _jobMgr;
119128
_svc.volFactory = _volFactory;
120129
_svc.volService = volService;
130+
_svc._userVmMgr = _userVmMgr;
131+
_svc._gson = GsonHelper.getGsonLogger();
121132

122133
// mock caller context
123134
AccountVO account = new AccountVO("admin", 1L, "networkDomain", Account.ACCOUNT_TYPE_NORMAL, "uuid");
@@ -383,6 +394,20 @@ public void testNonEmptyGetVolumeNameFromCmd() {
383394
Assert.assertSame(_svc.getVolumeNameFromCommand(createVol), "abc");
384395
}
385396

397+
@Test
398+
public void testUpdateMissingRootDiskControllerWithNullChainInfo() {
399+
_svc.updateMissingRootDiskController(null, null);
400+
verify(_svc._userVmMgr, times(0)).persistDeviceBusInfo(any(UserVmVO.class), anyString());
401+
}
402+
403+
@Test
404+
public void testUpdateMissingRootDiskControllerWithValidChainInfo() {
405+
UserVmVO vm = _svc._userVmDao.findById(1L);
406+
assert vm.getType() == VirtualMachine.Type.User;
407+
_svc.updateMissingRootDiskController(vm, "{\"diskDeviceBusName\":\"scsi0:0\",\"diskChain\":[\"[somedatastore] i-3-VM-somePath/ROOT-1.vmdk\"]}");
408+
verify(_svc._userVmMgr, times(1)).persistDeviceBusInfo(any(UserVmVO.class), eq("scsi"));
409+
}
410+
386411
@After
387412
public void tearDown() {
388413
CallContext.unregister();

0 commit comments

Comments
 (0)