Skip to content

Commit be2f06d

Browse files
committed
<fix>[compute]: <description
Resolves: ZSV-1 Change-Id: I746a6d7266686d637a6d76756861636a74766b74
1 parent e3362fe commit be2f06d

43 files changed

Lines changed: 1597 additions & 29 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
package org.zstack.compute.vm;
2+
3+
import org.springframework.beans.factory.annotation.Autowired;
4+
import org.zstack.core.cloudbus.CloudBusCallBack;
5+
import org.zstack.core.gc.GC;
6+
import org.zstack.core.gc.GCCompletion;
7+
import org.zstack.core.gc.TimeBasedGarbageCollector;
8+
import org.zstack.core.thread.ChainTask;
9+
import org.zstack.core.thread.SyncTaskChain;
10+
import org.zstack.core.thread.ThreadFacade;
11+
import org.zstack.header.core.progress.ChainInfo;
12+
import org.zstack.header.message.MessageReply;
13+
import org.zstack.header.vm.UpdateVmInstanceMetadataMsg;
14+
import org.zstack.header.vm.VmInstanceConstant;
15+
import org.zstack.header.vm.VmInstanceVO;
16+
17+
public class UpdateVmInstanceMetadataGC extends TimeBasedGarbageCollector {
18+
@GC
19+
public String vmInstanceUuid;
20+
21+
@Autowired
22+
protected ThreadFacade thdf;
23+
24+
static public String getUpdateVmInstanceMetadataSyncSignature(String vmInstanceUuid) {
25+
return String.format("update-vm-%s-metadata", vmInstanceUuid);
26+
}
27+
28+
@Override
29+
protected void triggerNow(GCCompletion completion) {
30+
if (!dbf.isExist(vmInstanceUuid, VmInstanceVO.class)) {
31+
completion.cancel();
32+
return;
33+
}
34+
35+
String queueName = getUpdateVmInstanceMetadataSyncSignature(vmInstanceUuid);
36+
ChainInfo chainInfo = thdf.getChainTaskInfo(queueName);
37+
if (!chainInfo.getPendingTask().isEmpty()) {
38+
completion.cancel();
39+
return;
40+
}
41+
42+
thdf.chainSubmit(new ChainTask(completion) {
43+
@Override
44+
public String getSyncSignature() {
45+
return queueName;
46+
}
47+
48+
@Override
49+
public void run(final SyncTaskChain chain) {
50+
UpdateVmInstanceMetadataMsg msg = new UpdateVmInstanceMetadataMsg();
51+
msg.setUuid(vmInstanceUuid);
52+
bus.makeTargetServiceIdByResourceUuid(msg, VmInstanceConstant.SERVICE_ID, vmInstanceUuid);
53+
bus.send(msg, new CloudBusCallBack(completion) {
54+
@Override
55+
public void run(MessageReply reply) {
56+
if (!reply.isSuccess()) {
57+
completion.fail(reply.getError());
58+
} else {
59+
completion.success();
60+
}
61+
chain.next();
62+
}
63+
});
64+
}
65+
66+
@Override
67+
public String getName() {
68+
return queueName;
69+
}
70+
});
71+
}
72+
}

compute/src/main/java/org/zstack/compute/vm/VmGlobalConfig.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,4 +133,10 @@ public class VmGlobalConfig {
133133
@GlobalConfigValidation(validValues = {"None", "AuthenticAMD"})
134134
@BindResourceConfig(value = {VmInstanceVO.class})
135135
public static GlobalConfig VM_CPUID_VENDOR = new GlobalConfig(CATEGORY, "vm.cpuid.vendor");
136+
137+
@GlobalConfigValidation(numberGreaterThan = 1)
138+
public static GlobalConfig GC_INTERVAL = new GlobalConfig(CATEGORY, "deletion.gcInterval");
139+
140+
@GlobalConfigValidation(validValues = {"true", "false"})
141+
public static GlobalConfig VM_METADATA = new GlobalConfig(CATEGORY, "vm.metadata");
136142
}

compute/src/main/java/org/zstack/compute/vm/VmInstanceApiInterceptor.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import org.zstack.header.message.APIMessage;
2222
import org.zstack.header.network.l2.*;
2323
import org.zstack.header.network.l3.*;
24+
import org.zstack.header.storage.primary.APIRegisterVmInstanceMsg;
2425
import org.zstack.header.storage.primary.PrimaryStorageClusterRefVO;
2526
import org.zstack.header.storage.primary.PrimaryStorageClusterRefVO_;
2627
import org.zstack.header.storage.snapshot.VolumeSnapshotVO;

compute/src/main/java/org/zstack/compute/vm/VmInstanceBase.java

Lines changed: 138 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,14 @@
1313
import org.zstack.core.cascade.CascadeFacade;
1414
import org.zstack.core.cloudbus.*;
1515
import org.zstack.core.componentloader.PluginRegistry;
16+
import org.zstack.core.config.GlobalConfig;
17+
import org.zstack.core.config.GlobalConfigDefinition;
1618
import org.zstack.core.db.*;
1719
import org.zstack.core.db.SimpleQuery.Op;
1820
import org.zstack.core.defer.Defer;
1921
import org.zstack.core.defer.Deferred;
22+
import org.zstack.core.gc.GCConstants;
23+
import org.zstack.core.gc.SubmitTimeBasedGarbageCollectorMsg;
2024
import org.zstack.core.jsonlabel.JsonLabel;
2125
import org.zstack.core.thread.ChainTask;
2226
import org.zstack.core.thread.RunInQueue;
@@ -45,6 +49,14 @@
4549
import org.zstack.header.message.*;
4650
import org.zstack.header.network.l3.*;
4751
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;
4860
import org.zstack.header.vm.*;
4961
import org.zstack.header.vm.ChangeVmMetaDataMsg.AtomicHostUuid;
5062
import org.zstack.header.vm.ChangeVmMetaDataMsg.AtomicVmState;
@@ -66,30 +78,29 @@
6678
import org.zstack.network.l3.L3NetworkManager;
6779
import org.zstack.network.service.DnsUtils;
6880
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;
7183
import org.zstack.tag.SystemTagCreator;
7284
import org.zstack.tag.SystemTagUtils;
7385
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.*;
7887
import org.zstack.utils.function.ForEachFunction;
7988
import org.zstack.utils.function.Function;
8089
import org.zstack.utils.gson.JSONObjectUtil;
8190
import org.zstack.utils.logging.CLogger;
82-
import org.zstack.utils.network.NicIpAddressInfo;
8391
import org.zstack.utils.network.IPv6Constants;
8492
import org.zstack.utils.network.IPv6NetworkUtils;
8593
import org.zstack.utils.network.NetworkUtils;
94+
import org.zstack.utils.network.NicIpAddressInfo;
8695

8796
import javax.persistence.PersistenceException;
8897
import javax.persistence.Tuple;
8998
import javax.persistence.TypedQuery;
99+
import java.lang.reflect.Field;
90100
import java.sql.Timestamp;
91101
import java.time.LocalDateTime;
92102
import java.util.*;
103+
import java.util.concurrent.TimeUnit;
93104
import java.util.stream.Collectors;
94105

95106
import static java.util.Arrays.asList;
@@ -140,6 +151,8 @@ public class VmInstanceBase extends AbstractVmInstance {
140151
private VmInstanceResourceMetadataManager vidm;
141152
@Autowired
142153
private NetworkServiceManager nwServiceMgr;
154+
@Autowired
155+
private ResourceDestinationMaker destMaker;
143156

144157
protected VmInstanceVO self;
145158
protected VmInstanceVO originalCopy;
@@ -533,6 +546,8 @@ protected void handleLocalMessage(Message msg) {
533546
handle((CancelFlattenVmInstanceMsg) msg);
534547
} else if (msg instanceof KvmReportVmShutdownEventMsg) {
535548
handle((KvmReportVmShutdownEventMsg) msg);
549+
} else if (msg instanceof UpdateVmInstanceMetadataMsg) {
550+
handle((UpdateVmInstanceMetadataMsg) msg);
536551
} else {
537552
VmInstanceBaseExtensionFactory ext = vmMgr.getVmInstanceBaseExtensionFactory(msg);
538553
if (ext != null) {
@@ -9369,5 +9384,121 @@ public void run(MessageReply reply) {
93699384
}
93709385
});
93719386
}
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+
}
93729503
}
93739504

compute/src/main/java/org/zstack/compute/vm/VmInstanceUtils.java

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,29 @@
22

33
import org.apache.commons.collections.CollectionUtils;
44
import org.zstack.core.Platform;
5+
import org.zstack.core.db.Q;
56
import org.zstack.header.configuration.InstanceOfferingInventory;
67
import org.zstack.header.errorcode.OperationFailureException;
7-
import org.zstack.header.vm.APIChangeInstanceOfferingMsg;
8-
import org.zstack.header.vm.APICreateVmInstanceMsg;
9-
import org.zstack.header.vm.CreateVmInstanceMsg;
10-
import org.zstack.header.vm.DiskAO;
11-
import org.zstack.header.vm.UpdateVmInstanceMsg;
12-
import org.zstack.header.vm.UpdateVmInstanceSpec;
13-
import org.zstack.header.vm.VmInstanceVO;
8+
import org.zstack.header.storage.snapshot.VolumeSnapshotInventory;
9+
import org.zstack.header.storage.snapshot.VolumeSnapshotVO;
10+
import org.zstack.header.storage.snapshot.VolumeSnapshotVO_;
11+
import org.zstack.header.storage.snapshot.group.VolumeSnapshotGroupRefVO;
12+
import org.zstack.header.storage.snapshot.group.VolumeSnapshotGroupRefVO_;
13+
import org.zstack.header.storage.snapshot.group.VolumeSnapshotGroupVO;
14+
import org.zstack.header.storage.snapshot.group.VolumeSnapshotGroupVO_;
15+
import org.zstack.header.tag.SystemTagVO;
16+
import org.zstack.header.tag.SystemTagVO_;
17+
import org.zstack.header.vm.*;
18+
import org.zstack.header.volume.VolumeVO;
19+
import org.zstack.header.volume.VolumeVO_;
20+
import org.zstack.resourceconfig.ResourceConfigVO;
21+
import org.zstack.resourceconfig.ResourceConfigVO_;
1422
import org.zstack.tag.SystemTagUtils;
23+
import org.zstack.utils.function.ForEachFunction;
24+
import org.zstack.utils.gson.JSONObjectUtil;
1525

16-
import java.util.ArrayList;
17-
import java.util.Iterator;
18-
import java.util.List;
19-
import java.util.Map;
20-
import java.util.Objects;
26+
import java.util.*;
27+
import java.util.stream.Collectors;
2128

2229
import static java.util.Objects.requireNonNull;
2330
import static org.zstack.compute.vm.VmSystemTags.PRIMARY_STORAGE_UUID_FOR_DATA_VOLUME;

conf/globalConfig/vm.xml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,4 +317,20 @@
317317
<type>java.lang.Boolean</type>
318318
<defaultValue>false</defaultValue>
319319
</config>
320+
321+
<config>
322+
<category>vm</category>
323+
<name>deletion.gcInterval</name>
324+
<description>update vm metadata interval</description>
325+
<type>java.lang.Long</type>
326+
<defaultValue>30</defaultValue>
327+
</config>
328+
329+
<config>
330+
<category>vm</category>
331+
<name>vm.metadata</name>
332+
<description>save vm metadata</description>
333+
<type>java.lang.Boolean</type>
334+
<defaultValue>false</defaultValue>
335+
</config>
320336
</globalConfig>

conf/serviceConfig/primaryStorage.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,4 +84,7 @@
8484
<message>
8585
<name>org.zstack.header.storage.primary.APIAddStorageProtocolMsg</name>
8686
</message>
87+
<message>
88+
<name>org.zstack.header.storage.primary.APIRegisterVmInstanceMsg</name>
89+
</message>
8790
</service>

core/src/main/java/org/zstack/core/gc/GarbageCollectorManagerImpl.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,8 @@ public void handleMessage(Message msg) {
255255
private void handleLocalMessage(Message msg) {
256256
if (msg instanceof TriggerGcJobMsg) {
257257
handle((TriggerGcJobMsg) msg);
258+
} else if (msg instanceof SubmitTimeBasedGarbageCollectorMsg) {
259+
handle((SubmitTimeBasedGarbageCollectorMsg) msg);
258260
} else {
259261
bus.dealWithUnknownMessage(msg);
260262
}
@@ -282,6 +284,12 @@ public String getName() {
282284
});
283285
}
284286

287+
private void handle(final SubmitTimeBasedGarbageCollectorMsg msg) {
288+
MessageReply reply = new MessageReply();
289+
msg.getGc().submit(msg.getGcInterval(), msg.getUnit());
290+
bus.reply(msg, reply);
291+
}
292+
285293
private void handleApiMessage(APIMessage msg) {
286294
if (msg instanceof APITriggerGCJobMsg) {
287295
handle((APITriggerGCJobMsg) msg);

0 commit comments

Comments
 (0)