@Override @Transactional( readOnly = true, noRollbackForClassName = {"org.zstack.header.errorcode.OperationFailureException"}) public void preVmMigration(VmInstanceInventory vm) { List<String> volUuids = CollectionUtils.transformToList( vm.getAllVolumes(), new Function<String, VolumeInventory>() { @Override public String call(VolumeInventory arg) { return arg.getUuid(); } }); String sql = "select count(ps) from PrimaryStorageVO ps, VolumeVO vol where ps.uuid = vol.primaryStorageUuid and" + " vol.uuid in (:volUuids) and ps.type = :ptype"; TypedQuery<Long> q = dbf.getEntityManager().createQuery(sql, Long.class); q.setParameter("volUuids", volUuids); q.setParameter("ptype", LocalStorageConstants.LOCAL_STORAGE_TYPE); q.setMaxResults(1); Long count = q.getSingleResult(); if (count > 0) { throw new OperationFailureException( errf.stringToOperationError( String.format( "unable to live migrate with local storage. The vm[uuid:%s] has volumes on local storage," + "to protect your data, please stop the vm and do the volume migration", vm.getUuid()))); } }
@Test public void test() throws ApiSenderException { EipInventory eip = deployer.eips.get("eip"); VmInstanceInventory vm = deployer.vms.get("TestVm"); VmNicInventory nic = vm.getVmNics().get(0); IpRangeInventory ipr = deployer.ipRanges.get("GuestIpRange"); String newIp = null; long s = NetworkUtils.ipv4StringToLong(ipr.getStartIp()); long e = NetworkUtils.ipv4StringToLong(ipr.getEndIp()); for (long l = s; s < e; s++) { String ip = NetworkUtils.longToIpv4String(l); if (!ip.equals(nic.getIp())) { newIp = ip; break; } } Assert.assertNotNull(newIp); api.stopVmInstance(vm.getUuid()); api.setStaticIp(vm.getUuid(), nic.getL3NetworkUuid(), newIp); EipVO eipvo = dbf.findByUuid(eip.getUuid(), EipVO.class); Assert.assertEquals(newIp, eipvo.getGuestIp()); }
@Override @Transactional(readOnly = true) public void preRecoverVm(VmInstanceInventory vm) { String rootVolUuid = vm.getRootVolumeUuid(); String sql = "select ps.uuid from PrimaryStorageVO ps, VolumeVO vol where ps.uuid = vol.primaryStorageUuid" + " and vol.uuid = :uuid and ps.type = :pstype"; TypedQuery<String> q = dbf.getEntityManager().createQuery(sql, String.class); q.setParameter("uuid", rootVolUuid); q.setParameter("pstype", LocalStorageConstants.LOCAL_STORAGE_TYPE); String psuuid = dbf.find(q); if (psuuid == null) { return; } sql = "select count(ref) from LocalStorageResourceRefVO ref where ref.resourceUuid = :uuid and ref.resourceType = :rtype"; TypedQuery<Long> rq = dbf.getEntityManager().createQuery(sql, Long.class); rq.setParameter("uuid", rootVolUuid); rq.setParameter("rtype", VolumeVO.class.getSimpleName()); long count = rq.getSingleResult(); if (count == 0) { throw new OperationFailureException( errf.stringToOperationError( String.format( "unable to recover the vm[uuid:%s, name:%s]. The vm's root volume is on the local" + " storage[uuid:%s]; however, the host on which the root volume is has been deleted", vm.getUuid(), vm.getName(), psuuid))); } }
@Test public void test() throws ApiSenderException { PrimaryStorageInventory local = deployer.primaryStorages.get("local"); VmInstanceInventory vm1 = deployer.vms.get("TestVm"); VmInstanceInventory vm2 = deployer.vms.get("TestVm1"); DiskOfferingInventory dof = deployer.diskOfferings.get("TestDiskOffering1"); VolumeInventory data = api.createDataVolume("data", dof.getUuid()); data = api.attachVolumeToVm(vm1.getUuid(), data.getUuid()); data = api.detachVolumeFromVm(data.getUuid()); List<VmInstanceInventory> vms = api.getDataVolumeCandidateVmForAttaching(data.getUuid()); Assert.assertEquals(1, vms.size()); api.localStorageMigrateVolume(data.getUuid(), vm2.getHostUuid(), null); vms = api.getDataVolumeCandidateVmForAttaching(data.getUuid()); Assert.assertEquals(1, vms.size()); Assert.assertEquals(vm2.getUuid(), vms.get(0).getUuid()); List<VolumeInventory> vols = api.getVmAttachableVolume(vm2.getUuid()); Assert.assertEquals(1, vols.size()); Assert.assertEquals(data.getUuid(), vols.get(0).getUuid()); vols = api.getVmAttachableVolume(vm1.getUuid()); Assert.assertEquals(0, vols.size()); api.localStorageMigrateVolume(data.getUuid(), vm1.getHostUuid(), null); vols = api.getVmAttachableVolume(vm1.getUuid()); Assert.assertEquals(1, vols.size()); Assert.assertEquals(data.getUuid(), vols.get(0).getUuid()); vols = api.getVmAttachableVolume(vm2.getUuid()); Assert.assertEquals(0, vols.size()); }
@Override protected FlowChain getStartVmWorkFlowChain(VmInstanceInventory inv) { FlowChain chain = super.getStartVmWorkFlowChain(inv); chain.setName(String.format("start-appliancevm-%s", inv.getUuid())); chain.insert( new Flow() { String __name__ = "change-appliancevm-status-to-connecting"; ApplianceVmStatus originStatus = getSelf().getStatus(); @Override public void run(FlowTrigger trigger, Map data) { getSelf().setStatus(ApplianceVmStatus.Connecting); self = dbf.updateAndRefresh(self); trigger.next(); } @Override public void rollback(FlowTrigger trigger, Map data) { self = dbf.reload(self); getSelf().setStatus(originStatus); self = dbf.updateAndRefresh(self); trigger.rollback(); } }); prepareLifeCycleInfo(chain); prepareFirewallInfo(chain); addBootstrapFlows(chain, HypervisorType.valueOf(inv.getHypervisorType())); List<Flow> subStartFlows = getPostStartFlows(); if (subStartFlows != null) { for (Flow f : subStartFlows) { chain.then(f); } } chain.then( new NoRollbackFlow() { String __name__ = "change-appliancevm-status-to-connected"; @Override public void run(FlowTrigger trigger, Map data) { getSelf().setStatus(ApplianceVmStatus.Connected); self = dbf.updateAndRefresh(self); trigger.next(); } }); boolean noRollbackOnFailure = ApplianceVmGlobalProperty.NO_ROLLBACK_ON_POST_FAILURE; chain.noRollback(noRollbackOnFailure); return chain; }
@Test public void test() throws ApiSenderException, InterruptedException { ImageInventory img = deployer.images.get("TestImage"); VmInstanceInventory vm = deployer.vms.get("TestVm"); api.deleteImage(img.getUuid()); api.stopVmInstance(vm.getUuid()); api.startVmInstance(vm.getUuid()); api.rebootVmInstance(vm.getUuid()); api.destroyVmInstance(vm.getUuid()); }
@Test public void test() throws ApiSenderException { VmInstanceInventory vm = deployer.vms.get("TestVm"); api.stopVmInstance(vm.getUuid()); PrimaryStorageInventory local = deployer.primaryStorages.get("local"); VolumeSnapshotInventory sp = api.createSnapshot(vm.getRootVolumeUuid()); Assert.assertFalse(kconfig.snapshotCmds.isEmpty()); LocalStorageResourceRefVO ref = dbf.findByUuid(sp.getUuid(), LocalStorageResourceRefVO.class); Assert.assertNotNull(ref); Assert.assertEquals(vm.getHostUuid(), ref.getHostUuid()); sp = api.createSnapshot(vm.getRootVolumeUuid()); ref = dbf.findByUuid(sp.getUuid(), LocalStorageResourceRefVO.class); Assert.assertNotNull(ref); Assert.assertEquals(vm.getHostUuid(), ref.getHostUuid()); sp = api.createSnapshot(vm.getRootVolumeUuid()); ref = dbf.findByUuid(sp.getUuid(), LocalStorageResourceRefVO.class); Assert.assertNotNull(ref); Assert.assertEquals(vm.getHostUuid(), ref.getHostUuid()); PrimaryStorageVO localvo = dbf.findByUuid(local.getUuid(), PrimaryStorageVO.class); long avail = localvo.getCapacity().getAvailableCapacity(); ImageInventory img = api.createTemplateFromSnapshot(sp.getUuid()); Assert.assertTrue(img.getSize() != 0); localvo = dbf.findByUuid(local.getUuid(), PrimaryStorageVO.class); Assert.assertEquals(avail, localvo.getCapacity().getAvailableCapacity()); }
@Test public void test() throws ApiSenderException { VmInstanceInventory vm = deployer.vms.get("TestVm"); api.stopVmInstance(vm.getUuid()); String rootVolumeUuid = vm.getRootVolumeUuid(); VolumeVO vol = dbf.findByUuid(rootVolumeUuid, VolumeVO.class); BackupStorageInventory sftp = deployer.backupStorages.get("sftp"); ImageInventory image = api.createTemplateFromRootVolume("testImage", rootVolumeUuid, (List) null); Assert.assertEquals(sftp.getUuid(), image.getBackupStorageRefs().get(0).getBackupStorageUuid()); Assert.assertEquals(ImageStatus.Ready.toString(), image.getStatus()); Assert.assertEquals(vol.getSize(), image.getSize()); Assert.assertEquals(String.format("volume://%s", vol.getUuid()), image.getUrl()); ImageVO ivo = dbf.findByUuid(image.getUuid(), ImageVO.class); Assert.assertNotNull(ivo); }
@Test public void test() throws ApiSenderException { L3NetworkInventory l3 = deployer.l3Networks.get("l3Network1"); InstanceOfferingInventory instanceOffering = deployer.instanceOfferings.get("instanceOffering512M512HZ"); ImageInventory imageInventory = deployer.images.get("image1"); ZoneInventory zone1 = deployer.zones.get("zone1"); VmCreator creator = new VmCreator(); creator.addL3Network(l3.getUuid()); creator.imageUuid = imageInventory.getUuid(); creator.instanceOfferingUuid = instanceOffering.getUuid(); creator.zoneUuid = zone1.getUuid(); VmInstanceInventory vm = creator.create(); HostCapacityVO cvo = dbf.findByUuid(vm.getHostUuid(), HostCapacityVO.class); Assert.assertEquals(instanceOffering.getCpuNum(), cvo.getUsedCpu()); Assert.assertEquals(instanceOffering.getMemorySize(), cvo.getUsedMemory()); Assert.assertEquals(zone1.getUuid(), vm.getZoneUuid()); }
@Test public void test() throws ApiSenderException { VmInstanceInventory vm = deployer.vms.get("TestVm"); ImageInventory iso = deployer.images.get("TestIso"); PrimaryStorageInventory ps = deployer.primaryStorages.get("ceph-pri"); restf.installBeforeAsyncJsonPostInterceptor( new BeforeAsyncJsonPostInterceptor() { @Override public void beforeAsyncJsonPost(String url, Object body, TimeUnit unit, long timeout) { if (body instanceof AttachIsoCmd) { AttachIsoCmd cmd = (AttachIsoCmd) body; isoto = (KvmCephIsoTO) cmd.iso; } } @Override public void beforeAsyncJsonPost(String url, String body, TimeUnit unit, long timeout) {} }); api.attachIso(vm.getUuid(), iso.getUuid(), null); Assert.assertNotNull(isoto); Assert.assertFalse(isoto.getMonInfo().isEmpty()); CephPrimaryStorageVO ceph = dbf.findByUuid(ps.getUuid(), CephPrimaryStorageVO.class); Assert.assertEquals(ceph.getMons().size(), isoto.getMonInfo().size()); for (final CephPrimaryStorageMonVO mon : ceph.getMons()) { MonInfo info = CollectionUtils.find( isoto.getMonInfo(), new Function<MonInfo, MonInfo>() { @Override public MonInfo call(MonInfo arg) { return arg.getHostname().equals(mon.getHostname()) ? arg : null; } }); Assert.assertNotNull(info); } }
@Test public void test() throws ApiSenderException, InterruptedException { VmInstanceInventory vm = deployer.vms.get("TestVm"); VolumeInventory root = CollectionUtils.find( vm.getAllVolumes(), new Function<VolumeInventory, VolumeInventory>() { @Override public VolumeInventory call(VolumeInventory arg) { return VolumeType.Root.toString().equals(arg.getType()) ? arg : null; } }); assert root != null; VolumeSnapshotInventory sp = api.createSnapshot(root.getUuid()); IscsiBtrfsSnapshotValidator validator = new IscsiBtrfsSnapshotValidator(); validator.validate(sp); VolumeInventory volume = api.createDataVolumeFromSnapshot(sp.getUuid()); Assert.assertEquals(VolumeConstant.VOLUME_FORMAT_RAW, volume.getFormat()); }
@Test public void test() throws ApiSenderException { final L3NetworkInventory l3 = deployer.l3Networks.get("TestL3Network4"); VmInstanceInventory vm = deployer.vms.get("TestVm"); vm = api.attachNic(vm.getUuid(), l3.getUuid()); Assert.assertEquals(4, vm.getVmNics().size()); VmNicInventory nic = vm.getVmNics().get(0); vm = api.detachNic(nic.getUuid()); Assert.assertEquals(3, vm.getVmNics().size()); Assert.assertFalse(config.detachNicCommands.isEmpty()); String l3Uuid = nic.getL3NetworkUuid(); nic = vm.findNic(l3Uuid); Assert.assertNull(nic); api.stopVmInstance(vm.getUuid()); vm = api.startVmInstance(vm.getUuid()); Assert.assertEquals(3, vm.getVmNics().size()); nic = vm.findNic(l3Uuid); Assert.assertNull(nic); }
@Override public void preAttachVolume(VmInstanceInventory vm, final VolumeInventory volume) { SimpleQuery<LocalStorageResourceRefVO> q = dbf.createQuery(LocalStorageResourceRefVO.class); q.add( LocalStorageResourceRefVO_.resourceUuid, Op.IN, list(vm.getRootVolumeUuid(), volume.getUuid())); q.groupBy(LocalStorageResourceRefVO_.hostUuid); long count = q.count(); if (count < 2) { return; } q = dbf.createQuery(LocalStorageResourceRefVO.class); q.select(LocalStorageResourceRefVO_.hostUuid); q.add(LocalStorageResourceRefVO_.resourceUuid, Op.EQ, vm.getRootVolumeUuid()); String rootHost = q.findValue(); q = dbf.createQuery(LocalStorageResourceRefVO.class); q.select(LocalStorageResourceRefVO_.hostUuid); q.add(LocalStorageResourceRefVO_.resourceUuid, Op.EQ, volume.getUuid()); String dataHost = q.findValue(); if (!rootHost.equals(dataHost)) { throw new OperationFailureException( errf.stringToOperationError( String.format( "cannot attach the data volume[uuid:%s] to the vm[uuid:%s]. Both vm's root volume and the data volume are" + " on local primary storage, but they are on different hosts. The root volume[uuid:%s] is on the host[uuid:%s] but the data volume[uuid: %s]" + " is on the host[uuid: %s]", volume.getUuid(), vm.getUuid(), vm.getRootVolumeUuid(), rootHost, volume.getUuid(), dataHost))); } }
@Test public void test() throws ApiSenderException { VmInstanceInventory vm = deployer.vms.get("TestVm"); ClusterInventory cluster1 = deployer.clusters.get("Cluster1"); HostInventory host1 = deployer.hosts.get("host1"); ClusterInventory cluster2 = deployer.clusters.get("Cluster2"); HostInventory host2 = deployer.hosts.get("host2"); boolean s = false; try { // vm is running, failure api.getVmStartingCandidateHosts(vm.getUuid(), null); } catch (ApiSenderException e) { s = true; } Assert.assertTrue(s); api.stopVmInstance(vm.getUuid()); APIGetVmStartingCandidateClustersHostsReply reply = api.getVmStartingCandidateHosts(vm.getUuid(), null); Assert.assertEquals(2, reply.getClusterInventories().size()); Assert.assertEquals(2, reply.getHostInventories().size()); }
@Test public void test() throws ApiSenderException { VmInstanceInventory vm = deployer.vms.get("TestVm"); VolumeInventory dataVol = CollectionUtils.find( vm.getAllVolumes(), new Function<VolumeInventory, VolumeInventory>() { @Override public VolumeInventory call(VolumeInventory arg) { if (arg.getType().equals(VolumeType.Data.toString())) { return arg; } return null; } }); String volUuid = dataVol.getUuid(); VolumeSnapshotInventory inv1 = api.createSnapshot(volUuid); fullSnapshot(inv1, 0); VolumeSnapshotInventory inv = api.createSnapshot(volUuid); deltaSnapshot(inv, 1); inv = api.createSnapshot(volUuid); deltaSnapshot(inv, 2); inv = api.createSnapshot(volUuid); deltaSnapshot(inv, 3); BackupStorageInventory sftp = deployer.backupStorages.get("sftp"); api.backupSnapshot(inv.getUuid()); api.deleteSnapshotFromBackupStorage(inv1.getUuid(), sftp.getUuid()); BackupStorageVO sftpvo = dbf.findByUuid(sftp.getUuid(), BackupStorageVO.class); Assert.assertEquals(sftp.getAvailableCapacity(), sftpvo.getAvailableCapacity()); }
@Test public void test() throws ApiSenderException, InterruptedException { VmInstanceInventory vm = deployer.vms.get("TestVm"); VolumeInventory root = CollectionUtils.find( vm.getAllVolumes(), new Function<VolumeInventory, VolumeInventory>() { @Override public VolumeInventory call(VolumeInventory arg) { return VolumeType.Root.toString().equals(arg.getType()) ? arg : null; } }); assert root != null; VolumeSnapshotInventory sp = api.createSnapshot(root.getUuid()); IscsiBtrfsSnapshotValidator validator = new IscsiBtrfsSnapshotValidator(); validator.validate(sp); Assert.assertEquals(1, iconfig.createSubVolumeCmds.size()); api.destroyVmInstance(vm.getUuid()); api.deleteSnapshot(sp.getUuid()); VolumeSnapshotVO spvo = dbf.findByUuid(sp.getUuid(), VolumeSnapshotVO.class); Assert.assertNull(spvo); }
@Test public void test() throws ApiSenderException, InterruptedException { VmInstanceInventory vm1 = deployer.vms.get("TestVm1"); VmInstanceInventory vm2 = deployer.vms.get("TestVm2"); api.setVmHaLevel(vm1.getUuid(), VmHaLevel.NeverStop, null); api.setVmHaLevel(vm2.getUuid(), VmHaLevel.OnHostFailure, null); api.maintainHost(vm1.getHostUuid()); HostInventory host2 = deployer.hosts.get("host2"); VmInstanceVO vmvo1 = dbf.findByUuid(vm1.getUuid(), VmInstanceVO.class); VmInstanceVO vmvo2 = dbf.findByUuid(vm2.getUuid(), VmInstanceVO.class); Assert.assertEquals(VmInstanceState.Running, vmvo1.getState()); Assert.assertEquals(host2.getUuid(), vmvo1.getHostUuid()); Assert.assertEquals(VmInstanceState.Stopped, vmvo2.getState()); }
@Override protected FlowChain getMigrateVmWorkFlowChain(VmInstanceInventory inv) { FlowChain chain = super.getMigrateVmWorkFlowChain(inv); chain.setName(String.format("migrate-appliancevm-%s", inv.getUuid())); prepareLifeCycleInfo(chain); prepareFirewallInfo(chain); List<Flow> subMigrateFlows = getPostMigrateFlows(); if (subMigrateFlows != null) { for (Flow f : subMigrateFlows) { chain.then(f); } } boolean noRollbackOnFailure = ApplianceVmGlobalProperty.NO_ROLLBACK_ON_POST_FAILURE; chain.noRollback(noRollbackOnFailure); return chain; }
@Test public void test() throws ApiSenderException, InterruptedException { CoreGlobalProperty.VM_TRACER_ON = false; IdentityGlobalConfig.SESSION_TIMEOUT.updateValue(TimeUnit.HOURS.toSeconds(1000)); api.prepare(); InstanceOfferingInventory ioinv = api.listInstanceOffering(null).get(0); ImageInventory iminv = api.listImage(null).get(0); List<DiskOfferingInventory> dinvs = api.listDiskOffering(null); List<L3NetworkInventory> nwinvs = api.listL3Network(null); List<String> nws = new ArrayList<String>(nwinvs.size()); for (L3NetworkInventory nwinv : nwinvs) { nws.add(nwinv.getUuid()); } for (int i = 0; i < vmNum; i++) { VmInstanceInventory vm = new VmInstanceInventory(); vm.setDescription("TestVm"); vm.setName("TestVm"); vm.setType(VmInstanceConstant.USER_VM_TYPE); vm.setInstanceOfferingUuid(ioinv.getUuid()); vm.setImageUuid(iminv.getUuid()); createVm(vm, dinvs.get(0).getUuid(), nws, new ArrayList<String>()); } latch.await(600, TimeUnit.MINUTES); long totalTime = 0; long minTime = 0; long maxTime = 0; for (Long t : timeCost) { minTime = Math.min(minTime, t); maxTime = Math.max(maxTime, t); totalTime += t; } System.out.println( String.format( "total time: %s, min time: %s, max time: %s, avg time: %s", TimeUnit.MILLISECONDS.toSeconds(totalTime), TimeUnit.MILLISECONDS.toSeconds(minTime), TimeUnit.MILLISECONDS.toSeconds(maxTime), TimeUnit.MILLISECONDS.toSeconds(totalTime / timeCost.size()))); /* SimpleQuery<VmInstanceVO> q = dbf.createQuery(VmInstanceVO.class); q.add(VmInstanceVO_.state, Op.EQ, VmInstanceState.Running); long count = q.count(); Assert.assertEquals(vmNum, count); */ TimeUnit.HOURS.sleep(1000); }
@Test public void test() throws ApiSenderException, InterruptedException { VmInstanceInventory vm = deployer.vms.get("TestVm"); final L3NetworkInventory l31 = deployer.l3Networks.get("TestL3Network1"); final L3NetworkInventory l32 = deployer.l3Networks.get("TestL3Network2"); VmNicInventory nic1 = CollectionUtils.find( vm.getVmNics(), new Function<VmNicInventory, VmNicInventory>() { @Override public VmNicInventory call(VmNicInventory arg) { return arg.getL3NetworkUuid().equals(l31.getUuid()) ? arg : null; } }); VmNicInventory nic2 = CollectionUtils.find( vm.getVmNics(), new Function<VmNicInventory, VmNicInventory>() { @Override public VmNicInventory call(VmNicInventory arg) { return arg.getL3NetworkUuid().equals(l32.getUuid()) ? arg : null; } }); VmInstanceInventory update = new VmInstanceInventory(); update.setUuid(vm.getUuid()); update.setDefaultL3NetworkUuid(l32.getUuid()); api.updateVm(update); TimeUnit.SECONDS.sleep(2); Assert.assertEquals(1, fconfig.resetDefaultGatewayCmds.size()); ResetDefaultGatewayCmd cmd = fconfig.resetDefaultGatewayCmds.get(0); Assert.assertEquals(nic1.getMac(), cmd.macOfGatewayToRemove); Assert.assertEquals(nic1.getGateway(), cmd.gatewayToRemove); Assert.assertEquals( new BridgeNameFinder().findByL3Uuid(l31.getUuid()), cmd.bridgeNameOfGatewayToRemove); Assert.assertEquals(nic2.getMac(), cmd.macOfGatewayToAdd); Assert.assertEquals(nic2.getGateway(), cmd.gatewayToAdd); Assert.assertEquals( new BridgeNameFinder().findByL3Uuid(l32.getUuid()), cmd.bridgeNameOfGatewayToAdd); }
private void handle(APIGetDataVolumeAttachableVmMsg msg) { APIGetDataVolumeAttachableVmReply reply = new APIGetDataVolumeAttachableVmReply(); reply.setInventories( VmInstanceInventory.valueOf(getCandidateVmForAttaching(msg.getSession().getAccountUuid()))); bus.reply(msg, reply); }
@Test public void test() throws ApiSenderException, InterruptedException { HostInventory host2 = deployer.hosts.get("host2"); HostInventory host1 = deployer.hosts.get("host1"); VmInstanceInventory vm = deployer.vms.get("TestVm"); PrimaryStorageInventory local = deployer.primaryStorages.get("local"); List<VolumeVO> vols = dbf.listAll(VolumeVO.class); List<VolumeVO> volumesOnLocal = new ArrayList<VolumeVO>(); ImageCacheVO cacheVO = dbf.listAll(ImageCacheVO.class).get(0); long imageSize = cacheVO.getSize(); long usedVolumeSize = 0; for (VolumeVO vol : vols) { if (vol.getPrimaryStorageUuid().equals(local.getUuid())) { volumesOnLocal.add(vol); usedVolumeSize += ratioMgr.calculateByRatio(vol.getPrimaryStorageUuid(), vol.getSize()); } } config.createEmptyVolumeCmds.clear(); config.deleteBitsCmds.clear(); vm = api.migrateVmInstance(vm.getUuid(), host2.getUuid()); TimeUnit.SECONDS.sleep(5); LocalStorageHostRefVO ref1 = dbf.findByUuid(host1.getUuid(), LocalStorageHostRefVO.class); Assert.assertEquals(ref1.getTotalCapacity() - imageSize, ref1.getAvailableCapacity()); LocalStorageHostRefVO ref2 = dbf.findByUuid(host2.getUuid(), LocalStorageHostRefVO.class); Assert.assertEquals( ref2.getTotalCapacity() - imageSize - usedVolumeSize, ref2.getAvailableCapacity()); Assert.assertEquals(volumesOnLocal.size(), config.createEmptyVolumeCmds.size()); for (final VolumeVO vol : volumesOnLocal) { // volumes are created on dst host CreateEmptyVolumeCmd cmd = CollectionUtils.find( config.createEmptyVolumeCmds, new Function<CreateEmptyVolumeCmd, CreateEmptyVolumeCmd>() { @Override public CreateEmptyVolumeCmd call(CreateEmptyVolumeCmd arg) { return arg.getVolumeUuid().equals(vol.getUuid()) ? arg : null; } }); Assert.assertNotNull(cmd); Assert.assertEquals(vol.getInstallPath(), cmd.getInstallUrl()); LocalStorageResourceRefVO r = dbf.findByUuid(vol.getUuid(), LocalStorageResourceRefVO.class); Assert.assertEquals(host2.getUuid(), r.getHostUuid()); // volumes are deleted on src host DeleteBitsCmd dcmd = CollectionUtils.find( config.deleteBitsCmds, new Function<DeleteBitsCmd, DeleteBitsCmd>() { @Override public DeleteBitsCmd call(DeleteBitsCmd arg) { return arg.getPath().equals(vol.getInstallPath()) ? arg : null; } }); Assert.assertNotNull( String.format( "no delete command for volume[uuid:%s, path:%s]", vol.getUuid(), vol.getInstallPath()), dcmd); } Assert.assertFalse(kconfig.migrateVmCmds.isEmpty()); MigrateVmCmd mcmd = kconfig.migrateVmCmds.get(0); Assert.assertEquals(host2.getManagementIp(), mcmd.getDestHostIp()); Assert.assertEquals(vm.getUuid(), mcmd.getVmUuid()); Assert.assertEquals( StorageMigrationPolicy.IncCopy.toString(), mcmd.getStorageMigrationPolicy()); }
@Override protected void startVmFromNewCreate( final StartNewCreatedVmInstanceMsg msg, final SyncTaskChain taskChain) { boolean callNext = true; try { refreshVO(); ErrorCode allowed = validateOperationByState(msg, self.getState(), null); if (allowed != null) { bus.replyErrorByMessageType(msg, allowed); return; } ErrorCode preCreated = extEmitter.preStartNewCreatedVm(msg.getVmInstanceInventory()); if (preCreated != null) { bus.replyErrorByMessageType(msg, preCreated); return; } StartNewCreatedApplianceVmMsg smsg = (StartNewCreatedApplianceVmMsg) msg; ApplianceVmSpec aspec = smsg.getApplianceVmSpec(); final VmInstanceSpec spec = new VmInstanceSpec(); spec.setVmInventory(msg.getVmInstanceInventory()); if (msg.getL3NetworkUuids() != null && !msg.getL3NetworkUuids().isEmpty()) { SimpleQuery<L3NetworkVO> nwquery = dbf.createQuery(L3NetworkVO.class); nwquery.add(L3NetworkVO_.uuid, SimpleQuery.Op.IN, msg.getL3NetworkUuids()); List<L3NetworkVO> vos = nwquery.list(); List<L3NetworkInventory> nws = L3NetworkInventory.valueOf(vos); spec.setL3Networks(nws); } else { spec.setL3Networks(new ArrayList<L3NetworkInventory>(0)); } if (msg.getDataDiskOfferingUuids() != null && !msg.getDataDiskOfferingUuids().isEmpty()) { SimpleQuery<DiskOfferingVO> dquery = dbf.createQuery(DiskOfferingVO.class); dquery.add(DiskOfferingVO_.uuid, SimpleQuery.Op.IN, msg.getDataDiskOfferingUuids()); List<DiskOfferingVO> vos = dquery.list(); // allow create multiple data volume from the same disk offering List<DiskOfferingInventory> disks = new ArrayList<DiskOfferingInventory>(); for (final String duuid : msg.getDataDiskOfferingUuids()) { DiskOfferingVO dvo = CollectionUtils.find( vos, new Function<DiskOfferingVO, DiskOfferingVO>() { @Override public DiskOfferingVO call(DiskOfferingVO arg) { if (duuid.equals(arg.getUuid())) { return arg; } return null; } }); disks.add(DiskOfferingInventory.valueOf(dvo)); } spec.setDataDiskOfferings(disks); } else { spec.setDataDiskOfferings(new ArrayList<DiskOfferingInventory>(0)); } ImageVO imvo = dbf.findByUuid(spec.getVmInventory().getImageUuid(), ImageVO.class); spec.getImageSpec().setInventory(ImageInventory.valueOf(imvo)); spec.putExtensionData(ApplianceVmConstant.Params.applianceVmSpec.toString(), aspec); spec.setCurrentVmOperation(VmInstanceConstant.VmOperation.NewCreate); spec.putExtensionData( ApplianceVmConstant.Params.applianceVmSubType.toString(), getSelf().getApplianceVmType()); changeVmStateInDb(VmInstanceStateEvent.starting); extEmitter.beforeStartNewCreatedVm(VmInstanceInventory.valueOf(self)); FlowChain chain = apvmf.getCreateApplianceVmWorkFlowBuilder().build(); chain.setName(String.format("create-appliancevm-%s", msg.getVmInstanceUuid())); chain.getData().put(VmInstanceConstant.Params.VmInstanceSpec.toString(), spec); chain .getData() .put( ApplianceVmConstant.Params.applianceVmFirewallRules.toString(), aspec.getFirewallRules()); addBootstrapFlows( chain, VolumeFormat.getMasterHypervisorTypeByVolumeFormat(imvo.getFormat())); List<Flow> subCreateFlows = getPostCreateFlows(); if (subCreateFlows != null) { for (Flow f : subCreateFlows) { chain.then(f); } } chain.then( new NoRollbackFlow() { String __name__ = "change-appliancevm-status-to-connected"; @Override public void run(FlowTrigger trigger, Map data) { // must reload here, otherwise it will override changes created by previous flows self = dbf.reload(self); getSelf().setStatus(ApplianceVmStatus.Connected); dbf.update(self); trigger.next(); } }); boolean noRollbackOnFailure = ApplianceVmGlobalProperty.NO_ROLLBACK_ON_POST_FAILURE; chain.noRollback(noRollbackOnFailure); chain .done( new FlowDoneHandler(msg, taskChain) { @Override public void handle(Map data) { VmInstanceSpec spec = (VmInstanceSpec) data.get(VmInstanceConstant.Params.VmInstanceSpec.toString()); self = dbf.reload(self); self.setLastHostUuid(spec.getDestHost().getUuid()); self.setHostUuid(spec.getDestHost().getUuid()); self.setClusterUuid(spec.getDestHost().getClusterUuid()); self.setZoneUuid(spec.getDestHost().getZoneUuid()); self.setHypervisorType(spec.getDestHost().getHypervisorType()); self.setRootVolumeUuid(spec.getDestRootVolume().getUuid()); changeVmStateInDb(VmInstanceStateEvent.running); logger.debug( String.format( "appliance vm[uuid:%s, name: %s, type:%s] is running ..", self.getUuid(), self.getName(), getSelf().getApplianceVmType())); VmInstanceInventory inv = VmInstanceInventory.valueOf(self); extEmitter.afterStartNewCreatedVm(inv); StartNewCreatedVmInstanceReply reply = new StartNewCreatedVmInstanceReply(); reply.setVmInventory(inv); bus.reply(msg, reply); taskChain.next(); } }) .error( new FlowErrorHandler(msg, taskChain) { @Override public void handle(ErrorCode errCode, Map data) { extEmitter.failedToStartNewCreatedVm(VmInstanceInventory.valueOf(self), errCode); dbf.remove(self); StartNewCreatedVmInstanceReply reply = new StartNewCreatedVmInstanceReply(); reply.setError(errCode); reply.setSuccess(false); bus.reply(msg, reply); taskChain.next(); } }) .start(); callNext = false; } finally { if (callNext) { taskChain.next(); } } }
@Test public void test() throws ApiSenderException, InterruptedException { final L3NetworkInventory l3 = deployer.l3Networks.get("TestL3Network4"); VmInstanceInventory vm = deployer.vms.get("TestVm"); APIGetIpAddressCapacityReply ipcap = api.getIpAddressCapacityByAll(); long avail1 = ipcap.getAvailableCapacity(); int num = 50; final CountDownLatch latch = new CountDownLatch(num); final String vmUuid = vm.getUuid(); class Ret { int count; } final Ret ret = new Ret(); for (int i = 0; i < num; i++) { new Runnable() { @Override @AsyncThread public void run() { try { VmInstanceInventory v = api.attachNic(vmUuid, l3.getUuid()); ret.count += 1; } catch (Exception e) { logger.warn(e.getMessage(), e); } finally { latch.countDown(); } } }.run(); } latch.await(120, TimeUnit.SECONDS); VmInstanceVO vmvo = dbf.findByUuid(vmUuid, VmInstanceVO.class); final CountDownLatch latch1 = new CountDownLatch(vmvo.getVmNics().size()); for (final VmNicVO nic : vmvo.getVmNics()) { new Runnable() { @Override @AsyncThread public void run() { try { api.detachNic(nic.getUuid()); } catch (Exception e) { logger.warn(e.getMessage(), e); } finally { latch1.countDown(); } } }.run(); } latch1.await(120, TimeUnit.SECONDS); TimeUnit.SECONDS.sleep(5); ipcap = api.getIpAddressCapacityByAll(); long avail2 = ipcap.getAvailableCapacity(); Assert.assertEquals(avail1, avail2 - 3); }
@Override @Transactional(readOnly = true) public List<VolumeVO> returnAttachableVolumes(VmInstanceInventory vm, List<VolumeVO> candidates) { // find instantiated volumes List<String> volUuids = CollectionUtils.transformToList( candidates, new Function<String, VolumeVO>() { @Override public String call(VolumeVO arg) { return VolumeStatus.Ready == arg.getStatus() ? arg.getUuid() : null; } }); if (volUuids.isEmpty()) { return candidates; } List<VolumeVO> uninstantiatedVolumes = CollectionUtils.transformToList( candidates, new Function<VolumeVO, VolumeVO>() { @Override public VolumeVO call(VolumeVO arg) { return arg.getStatus() == VolumeStatus.NotInstantiated ? arg : null; } }); String sql = "select ref.hostUuid from LocalStorageResourceRefVO ref where ref.resourceUuid = :volUuid and ref.resourceType = :rtype"; TypedQuery<String> q = dbf.getEntityManager().createQuery(sql, String.class); q.setParameter("volUuid", vm.getRootVolumeUuid()); q.setParameter("rtype", VolumeVO.class.getSimpleName()); List<String> ret = q.getResultList(); if (ret.isEmpty()) { return candidates; } String hostUuid = ret.get(0); sql = "select ref.resourceUuid from LocalStorageResourceRefVO ref where ref.resourceUuid in (:uuids) and ref.resourceType = :rtype" + " and ref.hostUuid != :huuid"; q = dbf.getEntityManager().createQuery(sql, String.class); q.setParameter("uuids", volUuids); q.setParameter("huuid", hostUuid); q.setParameter("rtype", VolumeVO.class.getSimpleName()); final List<String> toExclude = q.getResultList(); candidates = CollectionUtils.transformToList( candidates, new Function<VolumeVO, VolumeVO>() { @Override public VolumeVO call(VolumeVO arg) { return toExclude.contains(arg.getUuid()) ? null : arg; } }); candidates.addAll(uninstantiatedVolumes); return candidates; }
@Test public void test() throws ApiSenderException { StartVmCmd scmd = config.startVmCmd; Assert.assertTrue(scmd.getBootDev().contains(BootDev.cdrom.toString())); VmInstanceInventory vm = deployer.vms.get("TestVm"); List<String> order = api.getVmBootOrder(vm.getUuid(), null); Assert.assertEquals(1, order.size()); Assert.assertEquals(VmBootDevice.HardDisk.toString(), order.get(0)); vm = api.setVmBootOrder( vm.getUuid(), list(VmBootDevice.CdRom.toString(), VmBootDevice.HardDisk.toString()), null); Assert.assertTrue(VmSystemTags.BOOT_ORDER.hasTag(vm.getUuid())); vm = api.rebootVmInstance(vm.getUuid()); scmd = config.startVmCmd; Assert.assertTrue(scmd.getBootDev().contains(BootDev.cdrom.toString())); Assert.assertTrue(scmd.getBootDev().contains(BootDev.hd.toString())); order = api.getVmBootOrder(vm.getUuid(), null); Assert.assertEquals(2, order.size()); Assert.assertTrue(order.contains(VmBootDevice.CdRom.toString())); Assert.assertTrue(order.contains(VmBootDevice.HardDisk.toString())); api.stopVmInstance(vm.getUuid()); api.startVmInstance(vm.getUuid()); scmd = config.startVmCmd; Assert.assertTrue(scmd.getBootDev().contains(BootDev.cdrom.toString())); Assert.assertTrue(scmd.getBootDev().contains(BootDev.hd.toString())); config.rebootVmCmds.clear(); vm = api.setVmBootOrder(vm.getUuid(), null, null); Assert.assertFalse(VmSystemTags.BOOT_ORDER.hasTag(vm.getUuid())); order = api.getVmBootOrder(vm.getUuid(), null); Assert.assertEquals(1, order.size()); Assert.assertEquals(VmBootDevice.HardDisk.toString(), order.get(0)); api.rebootVmInstance(vm.getUuid()); scmd = config.startVmCmd; Assert.assertTrue(scmd.getBootDev().contains(BootDev.hd.toString())); api.stopVmInstance(vm.getUuid()); api.startVmInstance(vm.getUuid()); scmd = config.startVmCmd; Assert.assertTrue(scmd.getBootDev().contains(BootDev.hd.toString())); }
private List<VmInstanceInventory> vmFromDeleteAction(CascadeAction action) { List<VmInstanceInventory> ret = null; if (HostVO.class.getSimpleName().equals(action.getParentIssuer())) { List<HostInventory> hosts = action.getParentIssuerContext(); List<String> huuids = CollectionUtils.transformToList( hosts, new Function<String, HostInventory>() { @Override public String call(HostInventory arg) { return arg.getUuid(); } }); Map<String, VmInstanceVO> vmvos = new HashMap<String, VmInstanceVO>(); SimpleQuery<VmInstanceVO> q = dbf.createQuery(VmInstanceVO.class); q.add(VmInstanceVO_.hostUuid, SimpleQuery.Op.IN, huuids); q.add(VmInstanceVO_.type, Op.EQ, VmInstanceConstant.USER_VM_TYPE); List<VmInstanceVO> lst = q.list(); for (VmInstanceVO vo : lst) { vmvos.put(vo.getUuid(), vo); } if (ClusterVO.class.getSimpleName().equals(action.getRootIssuer())) { List<ClusterInventory> clusters = action.getRootIssuerContext(); List<String> clusterUuids = CollectionUtils.transformToList( clusters, new Function<String, ClusterInventory>() { @Override public String call(ClusterInventory arg) { return arg.getUuid(); } }); q = dbf.createQuery(VmInstanceVO.class); q.add(VmInstanceVO_.clusterUuid, Op.IN, clusterUuids); q.add(VmInstanceVO_.type, Op.EQ, VmInstanceConstant.USER_VM_TYPE); lst = q.list(); for (VmInstanceVO vo : lst) { vmvos.put(vo.getUuid(), vo); } } else if (ZoneVO.class.getSimpleName().equals(action.getRootIssuer())) { List<ZoneInventory> zones = action.getRootIssuerContext(); List<String> zoneUuids = CollectionUtils.transformToList( zones, new Function<String, ZoneInventory>() { @Override public String call(ZoneInventory arg) { return arg.getUuid(); } }); q = dbf.createQuery(VmInstanceVO.class); q.add(VmInstanceVO_.zoneUuid, Op.IN, zoneUuids); q.add(VmInstanceVO_.type, Op.EQ, VmInstanceConstant.USER_VM_TYPE); lst = q.list(); for (VmInstanceVO vo : lst) { vmvos.put(vo.getUuid(), vo); } } if (!vmvos.isEmpty()) { ret = VmInstanceInventory.valueOf(vmvos.values()); } } else if (NAME.equals(action.getParentIssuer())) { return action.getParentIssuerContext(); } else if (PrimaryStorageVO.class.getSimpleName().equals(action.getParentIssuer())) { final List<String> pruuids = CollectionUtils.transformToList( (List<PrimaryStorageInventory>) action.getParentIssuerContext(), new Function<String, PrimaryStorageInventory>() { @Override public String call(PrimaryStorageInventory arg) { return arg.getUuid(); } }); List<VmInstanceVO> vmvos = new Callable<List<VmInstanceVO>>() { @Override @Transactional(readOnly = true) public List<VmInstanceVO> call() { String sql = "select vm from VmInstanceVO vm, VolumeVO vol, PrimaryStorageVO pr where vm.type = :vmType and vm.uuid = vol.vmInstanceUuid" + " and vol.primaryStorageUuid = pr.uuid and vol.type = :volType and pr.uuid in (:uuids) group by vm.uuid"; TypedQuery<VmInstanceVO> q = dbf.getEntityManager().createQuery(sql, VmInstanceVO.class); q.setParameter("vmType", VmInstanceConstant.USER_VM_TYPE); q.setParameter("uuids", pruuids); q.setParameter("volType", VolumeType.Root); return q.getResultList(); } }.call(); if (!vmvos.isEmpty()) { ret = VmInstanceInventory.valueOf(vmvos); } } else if (L3NetworkVO.class.getSimpleName().equals(action.getParentIssuer())) { final List<String> l3uuids = CollectionUtils.transformToList( (List<L3NetworkInventory>) action.getParentIssuerContext(), new Function<String, L3NetworkInventory>() { @Override public String call(L3NetworkInventory arg) { return arg.getUuid(); } }); List<VmInstanceVO> vmvos = new Callable<List<VmInstanceVO>>() { @Override @Transactional(readOnly = true) public List<VmInstanceVO> call() { String sql = "select vm from VmInstanceVO vm, L3NetworkVO l3, VmNicVO nic where vm.type = :vmType and vm.uuid = nic.vmInstanceUuid and vm.state not in (:vmStates)" + " and nic.l3NetworkUuid = l3.uuid and l3.uuid in (:uuids) group by vm.uuid"; TypedQuery<VmInstanceVO> q = dbf.getEntityManager().createQuery(sql, VmInstanceVO.class); q.setParameter("vmType", VmInstanceConstant.USER_VM_TYPE); q.setParameter( "vmStates", Arrays.asList(VmInstanceState.Stopped, VmInstanceState.Stopping)); q.setParameter("uuids", l3uuids); return q.getResultList(); } }.call(); if (!vmvos.isEmpty()) { ret = VmInstanceInventory.valueOf(vmvos); } } else if (IpRangeVO.class.getSimpleName().equals(action.getParentIssuer())) { final List<String> ipruuids = CollectionUtils.transformToList( (List<IpRangeInventory>) action.getParentIssuerContext(), new Function<String, IpRangeInventory>() { @Override public String call(IpRangeInventory arg) { return arg.getUuid(); } }); List<VmInstanceVO> vmvos = new Callable<List<VmInstanceVO>>() { @Override @Transactional(readOnly = true) public List<VmInstanceVO> call() { String sql = "select vm from VmInstanceVO vm, VmNicVO nic, UsedIpVO ip, IpRangeVO ipr where vm.type = :vmType and vm.uuid = nic.vmInstanceUuid and vm.state not in (:vmStates)" + " and nic.usedIpUuid = ip.uuid and ip.ipRangeUuid = ipr.uuid and ipr.uuid in (:uuids) group by vm.uuid"; TypedQuery<VmInstanceVO> q = dbf.getEntityManager().createQuery(sql, VmInstanceVO.class); q.setParameter("vmType", VmInstanceConstant.USER_VM_TYPE); q.setParameter( "vmStates", Arrays.asList(VmInstanceState.Stopped, VmInstanceState.Stopping)); q.setParameter("uuids", ipruuids); return q.getResultList(); } }.call(); if (!vmvos.isEmpty()) { ret = VmInstanceInventory.valueOf(vmvos); } } else if (AccountVO.class.getSimpleName().equals(action.getParentIssuer())) { final List<String> auuids = CollectionUtils.transformToList( (List<AccountInventory>) action.getParentIssuerContext(), new Function<String, AccountInventory>() { @Override public String call(AccountInventory arg) { return arg.getUuid(); } }); List<VmInstanceVO> vmvos = new Callable<List<VmInstanceVO>>() { @Override @Transactional(readOnly = true) public List<VmInstanceVO> call() { String sql = "select d from VmInstanceVO d, AccountResourceRefVO r where d.uuid = r.resourceUuid and" + " r.resourceType = :rtype and r.accountUuid in (:auuids) group by d.uuid"; TypedQuery<VmInstanceVO> q = dbf.getEntityManager().createQuery(sql, VmInstanceVO.class); q.setParameter("rtype", VmInstanceVO.class.getSimpleName()); q.setParameter("auuids", auuids); return q.getResultList(); } }.call(); if (!vmvos.isEmpty()) { ret = VmInstanceInventory.valueOf(vmvos); } } return ret; }
private void handleDeletion(final CascadeAction action, final Completion completion) { int op = toDeletionOpCode(action); if (op == OP_NOPE) { completion.success(); return; } if (op == OP_REMOVE_INSTANCE_OFFERING) { if (VmGlobalConfig.UPDATE_INSTANCE_OFFERING_TO_NULL_WHEN_DELETING.value(Boolean.class)) { new Runnable() { @Override @Transactional public void run() { List<InstanceOfferingInventory> offerings = action.getParentIssuerContext(); List<String> offeringUuids = CollectionUtils.transformToList( offerings, new Function<String, InstanceOfferingInventory>() { @Override public String call(InstanceOfferingInventory arg) { return arg.getUuid(); } }); String sql = "update VmInstanceVO vm set vm.instanceOfferingUuid = null where vm.instanceOfferingUuid in (:offeringUuids)"; Query q = dbf.getEntityManager().createQuery(sql); q.setParameter("offeringUuids", offeringUuids); q.executeUpdate(); } }.run(); } completion.success(); return; } final List<VmInstanceInventory> vminvs = vmFromDeleteAction(action); if (vminvs == null) { completion.success(); return; } if (op == OP_STOP) { List<StopVmInstanceMsg> msgs = new ArrayList<StopVmInstanceMsg>(); for (VmInstanceInventory inv : vminvs) { StopVmInstanceMsg msg = new StopVmInstanceMsg(); msg.setVmInstanceUuid(inv.getUuid()); bus.makeTargetServiceIdByResourceUuid(msg, VmInstanceConstant.SERVICE_ID, inv.getUuid()); msgs.add(msg); } bus.send( msgs, 20, new CloudBusListCallBack(completion) { @Override public void run(List<MessageReply> replies) { if (!action.isActionCode(CascadeConstant.DELETION_FORCE_DELETE_CODE)) { for (MessageReply r : replies) { if (!r.isSuccess()) { completion.fail(r.getError()); return; } } } completion.success(); } }); } else if (op == OP_DELETION) { List<VmInstanceDeletionMsg> msgs = new ArrayList<VmInstanceDeletionMsg>(); for (VmInstanceInventory inv : vminvs) { VmInstanceDeletionMsg msg = new VmInstanceDeletionMsg(); msg.setForceDelete(action.isActionCode(CascadeConstant.DELETION_FORCE_DELETE_CODE)); msg.setVmInstanceUuid(inv.getUuid()); bus.makeTargetServiceIdByResourceUuid(msg, VmInstanceConstant.SERVICE_ID, inv.getUuid()); msgs.add(msg); } bus.send( msgs, 20, new CloudBusListCallBack(completion) { @Override public void run(List<MessageReply> replies) { if (!action.isActionCode(CascadeConstant.DELETION_FORCE_DELETE_CODE)) { for (MessageReply r : replies) { if (!r.isSuccess()) { completion.fail(r.getError()); return; } } } completion.success(); } }); } else if (op == OP_DETACH_NIC) { List<DetachNicFromVmMsg> msgs = new ArrayList<DetachNicFromVmMsg>(); List<L3NetworkInventory> l3s = action.getParentIssuerContext(); for (VmInstanceInventory vm : vminvs) { for (L3NetworkInventory l3 : l3s) { DetachNicFromVmMsg msg = new DetachNicFromVmMsg(); msg.setVmInstanceUuid(vm.getUuid()); msg.setVmNicUuid(vm.findNic(l3.getUuid()).getUuid()); bus.makeTargetServiceIdByResourceUuid(msg, VmInstanceConstant.SERVICE_ID, vm.getUuid()); msgs.add(msg); } } bus.send( msgs, new CloudBusListCallBack(completion) { @Override public void run(List<MessageReply> replies) { if (!action.isActionCode(CascadeConstant.DELETION_FORCE_DELETE_CODE)) { for (MessageReply r : replies) { if (!r.isSuccess()) { completion.fail(r.getError()); return; } } } completion.success(); } }); } }