|
13 | 13 | import org.zstack.core.cascade.CascadeFacade; |
14 | 14 | import org.zstack.core.cloudbus.*; |
15 | 15 | import org.zstack.core.componentloader.PluginRegistry; |
| 16 | +import org.zstack.core.config.GlobalConfig; |
| 17 | +import org.zstack.core.config.GlobalConfigDefinition; |
16 | 18 | import org.zstack.core.db.*; |
17 | 19 | import org.zstack.core.db.SimpleQuery.Op; |
18 | 20 | import org.zstack.core.defer.Defer; |
19 | 21 | import org.zstack.core.defer.Deferred; |
| 22 | +import org.zstack.core.gc.GCConstants; |
| 23 | +import org.zstack.core.gc.SubmitTimeBasedGarbageCollectorMsg; |
20 | 24 | import org.zstack.core.jsonlabel.JsonLabel; |
21 | 25 | import org.zstack.core.thread.ChainTask; |
22 | 26 | import org.zstack.core.thread.RunInQueue; |
|
45 | 49 | import org.zstack.header.message.*; |
46 | 50 | import org.zstack.header.network.l3.*; |
47 | 51 | import org.zstack.header.storage.primary.*; |
| 52 | +import org.zstack.header.storage.snapshot.*; |
| 53 | +import org.zstack.header.storage.snapshot.group.VolumeSnapshotGroupRefVO; |
| 54 | +import org.zstack.header.storage.snapshot.group.VolumeSnapshotGroupRefVO_; |
| 55 | +import org.zstack.header.storage.snapshot.group.VolumeSnapshotGroupVO; |
| 56 | +import org.zstack.header.storage.snapshot.group.VolumeSnapshotGroupVO_; |
| 57 | +import org.zstack.header.tag.SystemTagVO; |
| 58 | +import org.zstack.header.tag.SystemTagVO_; |
| 59 | +import org.zstack.header.tag.TagDefinition; |
48 | 60 | import org.zstack.header.vm.*; |
49 | 61 | import org.zstack.header.vm.ChangeVmMetaDataMsg.AtomicHostUuid; |
50 | 62 | import org.zstack.header.vm.ChangeVmMetaDataMsg.AtomicVmState; |
|
66 | 78 | import org.zstack.network.l3.L3NetworkManager; |
67 | 79 | import org.zstack.network.service.DnsUtils; |
68 | 80 | import org.zstack.network.service.NetworkServiceManager; |
69 | | -import org.zstack.resourceconfig.ResourceConfig; |
70 | | -import org.zstack.resourceconfig.ResourceConfigFacade; |
| 81 | +import org.zstack.resourceconfig.*; |
| 82 | +import org.zstack.tag.SystemTag; |
71 | 83 | import org.zstack.tag.SystemTagCreator; |
72 | 84 | import org.zstack.tag.SystemTagUtils; |
73 | 85 | import org.zstack.tag.TagManager; |
74 | | -import org.zstack.utils.CollectionUtils; |
75 | | -import org.zstack.utils.ExceptionDSL; |
76 | | -import org.zstack.utils.ObjectUtils; |
77 | | -import org.zstack.utils.Utils; |
| 86 | +import org.zstack.utils.*; |
78 | 87 | import org.zstack.utils.function.ForEachFunction; |
79 | 88 | import org.zstack.utils.function.Function; |
80 | 89 | import org.zstack.utils.gson.JSONObjectUtil; |
81 | 90 | import org.zstack.utils.logging.CLogger; |
82 | | -import org.zstack.utils.network.NicIpAddressInfo; |
83 | 91 | import org.zstack.utils.network.IPv6Constants; |
84 | 92 | import org.zstack.utils.network.IPv6NetworkUtils; |
85 | 93 | import org.zstack.utils.network.NetworkUtils; |
| 94 | +import org.zstack.utils.network.NicIpAddressInfo; |
86 | 95 |
|
87 | 96 | import javax.persistence.PersistenceException; |
88 | 97 | import javax.persistence.Tuple; |
89 | 98 | import javax.persistence.TypedQuery; |
| 99 | +import java.lang.reflect.Field; |
90 | 100 | import java.sql.Timestamp; |
91 | 101 | import java.time.LocalDateTime; |
92 | 102 | import java.util.*; |
| 103 | +import java.util.concurrent.TimeUnit; |
93 | 104 | import java.util.stream.Collectors; |
94 | 105 |
|
95 | 106 | import static java.util.Arrays.asList; |
@@ -140,6 +151,8 @@ public class VmInstanceBase extends AbstractVmInstance { |
140 | 151 | private VmInstanceResourceMetadataManager vidm; |
141 | 152 | @Autowired |
142 | 153 | private NetworkServiceManager nwServiceMgr; |
| 154 | + @Autowired |
| 155 | + private ResourceDestinationMaker destMaker; |
143 | 156 |
|
144 | 157 | protected VmInstanceVO self; |
145 | 158 | protected VmInstanceVO originalCopy; |
@@ -533,6 +546,8 @@ protected void handleLocalMessage(Message msg) { |
533 | 546 | handle((CancelFlattenVmInstanceMsg) msg); |
534 | 547 | } else if (msg instanceof KvmReportVmShutdownEventMsg) { |
535 | 548 | handle((KvmReportVmShutdownEventMsg) msg); |
| 549 | + } else if (msg instanceof UpdateVmInstanceMetadataMsg) { |
| 550 | + handle((UpdateVmInstanceMetadataMsg) msg); |
536 | 551 | } else { |
537 | 552 | VmInstanceBaseExtensionFactory ext = vmMgr.getVmInstanceBaseExtensionFactory(msg); |
538 | 553 | if (ext != null) { |
@@ -9369,5 +9384,121 @@ public void run(MessageReply reply) { |
9369 | 9384 | } |
9370 | 9385 | }); |
9371 | 9386 | } |
| 9387 | + |
| 9388 | + private void handle(UpdateVmInstanceMetadataMsg msg) { |
| 9389 | + Tuple tuple = Q.New(VolumeVO.class).select(VolumeVO_.primaryStorageUuid, VolumeVO_.uuid) |
| 9390 | + .eq(VolumeVO_.vmInstanceUuid, msg.getUuid()).eq(VolumeVO_.type, VolumeType.Root).findTuple(); |
| 9391 | + String primaryStorageUuid = tuple.get(0, String.class); |
| 9392 | + String rootVolumeUuid = tuple.get(1, String.class); |
| 9393 | + |
| 9394 | + UpdateVmInstanceMetadataOnPrimaryStorageMsg umsg = new UpdateVmInstanceMetadataOnPrimaryStorageMsg(); |
| 9395 | + umsg.setMetadata(buildVmInstanceMetadata(msg.getUuid())); |
| 9396 | + umsg.setPrimaryStorageUuid(primaryStorageUuid); |
| 9397 | + umsg.setRootVolumeUuid(rootVolumeUuid); |
| 9398 | + bus.makeTargetServiceIdByResourceUuid(umsg, PrimaryStorageConstant.SERVICE_ID, umsg.getPrimaryStorageUuid()); |
| 9399 | + bus.send(umsg, new CloudBusCallBack(msg) { |
| 9400 | + @Override |
| 9401 | + public void run(MessageReply r) { |
| 9402 | + UpdateVmInstanceMetadataOnPrimaryStorageReply reply = new UpdateVmInstanceMetadataOnPrimaryStorageReply(); |
| 9403 | + |
| 9404 | + if (!r.isSuccess()) { |
| 9405 | + reply.setError(Platform.operr("failed to update vm[uuid=%s] on hypervisor.", self.getUuid()) |
| 9406 | + .withCause(r.getError())); |
| 9407 | + |
| 9408 | + submitUpdateVmInstanceMetadataGC(); |
| 9409 | + return; |
| 9410 | + } |
| 9411 | + bus.reply(msg, reply); |
| 9412 | + } |
| 9413 | + |
| 9414 | + private void submitUpdateVmInstanceMetadataGC() { |
| 9415 | + SubmitTimeBasedGarbageCollectorMsg gcmsg = new SubmitTimeBasedGarbageCollectorMsg(); |
| 9416 | + gcmsg.setGcInterval(VmGlobalConfig.GC_INTERVAL.value(Long.class)); |
| 9417 | + gcmsg.setUnit(TimeUnit.SECONDS); |
| 9418 | + |
| 9419 | + UpdateVmInstanceMetadataGC gc = new UpdateVmInstanceMetadataGC(); |
| 9420 | + gc.vmInstanceUuid = self.getUuid(); |
| 9421 | + gc.NAME = String.format("gc-update-vm-%s-metadata", msg.getVmInstanceUuid()); |
| 9422 | + gcmsg.setGc(gc); |
| 9423 | + |
| 9424 | + bus.makeTargetServiceIdByResourceUuid(gcmsg, GCConstants.SERVICE_ID, msg.getVmInstanceUuid()); |
| 9425 | + bus.send(gcmsg); |
| 9426 | + } |
| 9427 | + }); |
| 9428 | + } |
| 9429 | + |
| 9430 | + private String buildVmInstanceMetadata(String vmInstanceUuid) { |
| 9431 | + VmMetadata vmMetadata = new VmMetadata(); |
| 9432 | + |
| 9433 | + // 找出vm |
| 9434 | + // 找出volume和快照 |
| 9435 | + // 找出网卡 |
| 9436 | + VmInstanceVO vm = Q.New(VmInstanceVO.class).eq(VmInstanceVO_.uuid, vmInstanceUuid).find(); |
| 9437 | + vmMetadata.vmSystemTags = getResourceSystemTagFromDb(vm.getUuid()); |
| 9438 | + vmMetadata.vmResourceConfigs = getResourceConfigFromDb(vm.getUuid()); |
| 9439 | + |
| 9440 | + // volume |
| 9441 | + // 挂载的 |
| 9442 | + List<VolumeVO> volumes1 = Q.New(VolumeVO.class).eq(VolumeVO_.vmInstanceUuid, vmInstanceUuid).list(); |
| 9443 | + // 被卸载的 |
| 9444 | + List<VolumeVO> volumes2 = Q.New(VolumeVO.class).eq(VolumeVO_.vmInstanceUuid, null).eq(VolumeVO_.lastVmInstanceUuid, vmInstanceUuid).list(); |
| 9445 | + |
| 9446 | + List<VolumeVO> volumes = new ArrayList<>(); |
| 9447 | + volumes.addAll(volumes1); |
| 9448 | + volumes.addAll(volumes2); |
| 9449 | + volumes.forEach(volume -> { |
| 9450 | + vmMetadata.volumeSystemTags.put(volume.getUuid(), getResourceSystemTagFromDb(volume.getUuid())); |
| 9451 | + vmMetadata.volumeResourceConfigs.put(volume.getUuid(), getResourceConfigFromDb(volume.getUuid())); |
| 9452 | + }); |
| 9453 | + |
| 9454 | + // snapshot |
| 9455 | + List<String> volumeUuids = volumes.stream().map(VolumeVO::getUuid).collect(Collectors.toList()); |
| 9456 | + List<VolumeSnapshotVO> snapshot = Q.New(VolumeSnapshotVO.class).in(VolumeSnapshotVO_.volumeUuid, volumeUuids).list(); |
| 9457 | + |
| 9458 | + List<VolumeSnapshotGroupVO> group = Q.New(VolumeSnapshotGroupVO.class).eq(VolumeSnapshotGroupVO_.vmInstanceUuid, vmInstanceUuid).list(); |
| 9459 | + List<String> groupUuids = group.stream().map(VolumeSnapshotGroupVO::getUuid).collect(Collectors.toList()); |
| 9460 | + List<VolumeSnapshotGroupRefVO> groupRef = Q.New(VolumeSnapshotGroupRefVO.class).in(VolumeSnapshotGroupRefVO_.volumeSnapshotGroupUuid, groupUuids).list(); |
| 9461 | + |
| 9462 | + // vm nic |
| 9463 | + List<VmNicVO> vmNics = Q.New(VmNicVO.class).eq(VmNicVO_.vmInstanceUuid, vmInstanceUuid).list(); |
| 9464 | + vmNics.forEach(nic -> { |
| 9465 | + vmMetadata.vmNicSystemTags.put(nic.getUuid(), getResourceSystemTagFromDb(nic.getUuid())); |
| 9466 | + vmMetadata.vmNicResourceConfigs.put(nic.getUuid(), getResourceConfigFromDb(nic.getUuid())); |
| 9467 | + }); |
| 9468 | + |
| 9469 | + // build metadata |
| 9470 | + vmMetadata.vmInstanceVO = JSONObjectUtil.toJsonString(vm); |
| 9471 | + volumes.forEach(volumeVO -> vmMetadata.volumeVOs.add(JSONObjectUtil.toJsonString(volumeVO))); |
| 9472 | + vmNics.forEach(nic -> vmMetadata.vmNicVOs.add(JSONObjectUtil.toJsonString(nic))); |
| 9473 | + |
| 9474 | + Map<String, List<String>> volumeSnapshots = new HashMap<>(); |
| 9475 | + snapshot.forEach(s -> { |
| 9476 | + if (volumeSnapshots.containsKey(s.getVolumeUuid())) { |
| 9477 | + volumeSnapshots.get(s.getVolumeUuid()).add(JSONObjectUtil.toJsonString(VolumeSnapshotInventory.valueOf(s))); |
| 9478 | + } else { |
| 9479 | + volumeSnapshots.put(s.getVolumeUuid(), new ArrayList<>()); |
| 9480 | + volumeSnapshots.get(s.getVolumeUuid()).add(JSONObjectUtil.toJsonString(VolumeSnapshotInventory.valueOf(s))); |
| 9481 | + } |
| 9482 | + }); |
| 9483 | + vmMetadata.volumeSnapshots = volumeSnapshots; |
| 9484 | + vmMetadata.volumeSnapshotGroupVO = group.stream().map(JSONObjectUtil::toJsonString).collect(Collectors.toList()); |
| 9485 | + vmMetadata.volumeSnapshotGroupRefVO = groupRef.stream().map(JSONObjectUtil::toJsonString).collect(Collectors.toList()); |
| 9486 | + |
| 9487 | + return JSONObjectUtil.toJsonString(vmMetadata); |
| 9488 | + } |
| 9489 | + |
| 9490 | + private List<String> getResourceSystemTagFromDb(String resourceUuid) { |
| 9491 | + List<String> systemTags = new ArrayList<>(); |
| 9492 | + List<SystemTagVO> vos = Q.New(SystemTagVO.class).eq(SystemTagVO_.resourceUuid, resourceUuid).list(); |
| 9493 | + vos.forEach(vo -> systemTags.add(JSONObjectUtil.toJsonString(vo))); |
| 9494 | + return systemTags; |
| 9495 | + } |
| 9496 | + |
| 9497 | + private List<String> getResourceConfigFromDb(String resourceUuid) { |
| 9498 | + List<String> resourceConfigs = new ArrayList<>(); |
| 9499 | + List<ResourceConfigVO> vos = Q.New(ResourceConfigVO.class).eq(ResourceConfigVO_.resourceUuid, resourceUuid).list(); |
| 9500 | + vos.forEach(vo -> resourceConfigs.add(JSONObjectUtil.toJsonString(vo))); |
| 9501 | + return resourceConfigs; |
| 9502 | + } |
9372 | 9503 | } |
9373 | 9504 |
|
0 commit comments