|
29 | 29 | import org.zstack.header.message.MessageReply; |
30 | 30 | import org.zstack.header.network.l2.L2NetworkConstant; |
31 | 31 | import org.zstack.header.network.l2.L2NetworkDetachStruct; |
| 32 | +import org.zstack.header.network.l2.L2NetworkInventory; |
32 | 33 | import org.zstack.header.network.l2.L2NetworkVO; |
33 | 34 | import org.zstack.header.network.l3.*; |
34 | 35 | import org.zstack.header.vm.*; |
@@ -105,6 +106,10 @@ protected int toDeletionOpCode(CascadeAction action) { |
105 | 106 | return OP_DETACH_NIC; |
106 | 107 | } |
107 | 108 |
|
| 109 | + if (L2NetworkVO.class.getSimpleName().equals(action.getParentIssuer())) { |
| 110 | + return OP_DETACH_NIC; |
| 111 | + } |
| 112 | + |
108 | 113 | if (VmInstanceVO.class.getSimpleName().equals(action.getParentIssuer())) { |
109 | 114 | return OP_DELETION; |
110 | 115 | } |
@@ -328,6 +333,32 @@ protected List<DetachNicFromVmMsg> handleDeletionForIpRange(List<VmDeletionStruc |
328 | 333 | return msgs; |
329 | 334 | } |
330 | 335 |
|
| 336 | + protected List<DetachNicFromVmMsg> handleDeletionForL2Network(List<VmDeletionStruct> vminvs, List<L2NetworkInventory> l2s) { |
| 337 | + List<DetachNicFromVmMsg> msgs = new ArrayList<>(); |
| 338 | + List<String> l2Uuids = l2s.stream().map(L2NetworkInventory::getUuid).collect(Collectors.toList()); |
| 339 | + List<String> l3Uuids = Q.New(L3NetworkVO.class).in(L3NetworkVO_.l2NetworkUuid, l2Uuids) |
| 340 | + .select(L3NetworkVO_.uuid).listValues(); |
| 341 | + if (l3Uuids.isEmpty()) { |
| 342 | + return msgs; |
| 343 | + } |
| 344 | + |
| 345 | + for (VmDeletionStruct vm : vminvs) { |
| 346 | + for (VmNicInventory nic : vm.getInventory().getVmNics()) { |
| 347 | + if (!l3Uuids.contains(nic.getL3NetworkUuid())) { |
| 348 | + continue; |
| 349 | + } |
| 350 | + |
| 351 | + DetachNicFromVmMsg msg = new DetachNicFromVmMsg(); |
| 352 | + msg.setVmInstanceUuid(nic.getVmInstanceUuid()); |
| 353 | + msg.setVmNicUuid(nic.getUuid()); |
| 354 | + bus.makeTargetServiceIdByResourceUuid(msg, VmInstanceConstant.SERVICE_ID, vm.getInventory().getUuid()); |
| 355 | + msgs.add(msg); |
| 356 | + } |
| 357 | + } |
| 358 | + |
| 359 | + return msgs; |
| 360 | + } |
| 361 | + |
331 | 362 | protected void handleDeletion(final CascadeAction action, final Completion completion) { |
332 | 363 | int op = toDeletionOpCode(action); |
333 | 364 | if (op == OP_NOPE) { |
@@ -492,6 +523,10 @@ public void done(ErrorCodeList errorCodeList) { |
492 | 523 | List<IpRangeInventory> iprs = action.getParentIssuerContext(); |
493 | 524 | List<DetachNicFromVmMsg> dmsgs = handleDeletionForIpRange(vminvs, iprs); |
494 | 525 | msgs.addAll(dmsgs); |
| 526 | + } else if (L2NetworkVO.class.getSimpleName().equals(action.getParentIssuer())) { |
| 527 | + List<L2NetworkInventory> l2s = action.getParentIssuerContext(); |
| 528 | + List<DetachNicFromVmMsg> dmsgs = handleDeletionForL2Network(vminvs, l2s); |
| 529 | + msgs.addAll(dmsgs); |
495 | 530 | } |
496 | 531 |
|
497 | 532 | detachVmNicCascade(msgs, true, completion); |
@@ -671,6 +706,40 @@ public List<VmInstanceVO> call() { |
671 | 706 | } |
672 | 707 | }.call(); |
673 | 708 |
|
| 709 | + if (!vmvos.isEmpty()) { |
| 710 | + ret = toVmDeletionStruct(vmvos); |
| 711 | + } |
| 712 | + } else if (L2NetworkVO.class.getSimpleName().equals(action.getParentIssuer())) { |
| 713 | + final List<String> l2uuids = CollectionUtils.transformToList( |
| 714 | + (List<L2NetworkInventory>) action.getParentIssuerContext(), |
| 715 | + new Function<String, L2NetworkInventory>() { |
| 716 | + @Override |
| 717 | + public String call(L2NetworkInventory arg) { |
| 718 | + return arg.getUuid(); |
| 719 | + } |
| 720 | + }); |
| 721 | + |
| 722 | + List<VmInstanceVO> vmvos = new Callable<List<VmInstanceVO>>() { |
| 723 | + @Override |
| 724 | + @Transactional(readOnly = true) |
| 725 | + public List<VmInstanceVO> call() { |
| 726 | + String sql = "select vm from VmInstanceVO vm, VmNicVO nic, L3NetworkVO l3" + |
| 727 | + " where vm.type = :vmType" + |
| 728 | + " and vm.uuid = nic.vmInstanceUuid" + |
| 729 | + " and vm.state in (:vmStates)" + |
| 730 | + " and nic.l3NetworkUuid = l3.uuid" + |
| 731 | + " and l3.l2NetworkUuid in (:uuids)" + |
| 732 | + " group by vm.uuid"; |
| 733 | + TypedQuery<VmInstanceVO> q = dbf.getEntityManager().createQuery(sql, VmInstanceVO.class); |
| 734 | + q.setParameter("vmType", VmInstanceConstant.USER_VM_TYPE); |
| 735 | + q.setParameter("vmStates", Arrays.asList( |
| 736 | + VmInstanceState.Stopped, VmInstanceState.Paused, |
| 737 | + VmInstanceState.Running, VmInstanceState.Destroyed)); |
| 738 | + q.setParameter("uuids", l2uuids); |
| 739 | + return q.getResultList(); |
| 740 | + } |
| 741 | + }.call(); |
| 742 | + |
674 | 743 | if (!vmvos.isEmpty()) { |
675 | 744 | ret = toVmDeletionStruct(vmvos); |
676 | 745 | } |
|
0 commit comments