Skip to content

Commit

Permalink
Support check cpu model
Browse files Browse the repository at this point in the history
Resolves ZSTAC-8778

Signed-off-by: AlanJager <[email protected]>
  • Loading branch information
AlanJager committed Mar 19, 2018
1 parent a130d25 commit a6f3783
Show file tree
Hide file tree
Showing 9 changed files with 338 additions and 7 deletions.
8 changes: 8 additions & 0 deletions conf/globalConfig/kvm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -89,4 +89,12 @@
<type>java.lang.Boolean</type>
<defaultValue>true</defaultValue>
</config>

<config>
<category>kvm</category>
<name>checkHostCpuModelName</name>
<description>whether check host cpu model name when migrate vm</description>
<type>java.lang.Boolean</type>
<defaultValue>false</defaultValue>
</config>
</globalConfig>
9 changes: 9 additions & 0 deletions plugin/kvm/src/main/java/org/zstack/kvm/KVMAgentCommands.java
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ public static class HostFactResponse extends AgentResponse {
private String qemuImgVersion;
private String libvirtVersion;
private String hvmCpuFlag;
private String cpuModelName;
private List<String> ipAddresses;

public String getHvmCpuFlag() {
Expand Down Expand Up @@ -279,6 +280,14 @@ public List<String> getIpAddresses() {
public void setIpAddresses(List<String> ipAddresses) {
this.ipAddresses = ipAddresses;
}

public String getCpuModelName() {
return cpuModelName;
}

public void setCpuModelName(String cpuModelName) {
this.cpuModelName = cpuModelName;
}
}

public static class HostCapacityCmd extends AgentCommand {
Expand Down
2 changes: 2 additions & 0 deletions plugin/kvm/src/main/java/org/zstack/kvm/KVMGlobalConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,6 @@ public class KVMGlobalConfig {
public static GlobalConfig NESTED_VIRTUALIZATION = new GlobalConfig(CATEGORY, "vm.cpuMode");
@GlobalConfigValidation
public static GlobalConfig VM_SYNC_ON_HOST_PING = new GlobalConfig(CATEGORY, "vmSyncOnHostPing");
@GlobalConfigValidation
public static GlobalConfig CHECK_HOST_CPU_MODEL_NAME = new GlobalConfig(CATEGORY, "checkHostCpuModelName");
}
61 changes: 58 additions & 3 deletions plugin/kvm/src/main/java/org/zstack/kvm/KVMHost.java
Original file line number Diff line number Diff line change
Expand Up @@ -2518,9 +2518,23 @@ public void connectHook(final ConnectHostInfo info, final Completion complete) {
creator.create();
}

if (null == KVMSystemTags.CPU_MODEL_NAME.getTokenByResourceUuid(self.getUuid(), KVMSystemTags.CPU_MODEL_NAME_TOKEN)) {
creator = KVMSystemTags.CPU_MODEL_NAME.newSystemTagCreator(self.getUuid());
creator.setTagByTokens(map(e(KVMSystemTags.CPU_MODEL_NAME_TOKEN, "Intel(R) Xeon(R) CPU E5-2630 v4 @ 2.20GHz")));
creator.inherent = true;
creator.create();
}

if (!checkQemuLibvirtVersionOfHost()) {
complete.fail(operr("host [uuid:%s] cannot be added to cluster [uuid:%s] because qemu/libvirt version does not match",
self.getUuid(), self.getClusterUuid()));
return;
}

if (KVMGlobalConfig.CHECK_HOST_CPU_MODEL_NAME.value(Boolean.class) && !checkCpuModelOfHost()) {
complete.fail(operr("host [uuid:%s] cannot be added to cluster [uuid:%s] because cpu model name does not match",
self.getUuid(), self.getClusterUuid()));
return;
}
}

Expand Down Expand Up @@ -2738,6 +2752,11 @@ public void success(HostFactResponse ret) {
creator.recreate = true;
creator.create();

creator = KVMSystemTags.CPU_MODEL_NAME.newSystemTagCreator(self.getUuid());
creator.setTagByTokens(map(e(KVMSystemTags.CPU_MODEL_NAME_TOKEN, ret.getCpuModelName())));
creator.recreate = true;
creator.create();

if (ret.getLibvirtVersion().compareTo(KVMConstant.MIN_LIBVIRT_VIRTIO_SCSI_VERSION) >= 0) {
creator = KVMSystemTags.VIRTIO_SCSI.newSystemTagCreator(self.getUuid());
creator.recreate = true;
Expand Down Expand Up @@ -2772,12 +2791,19 @@ public void fail(ErrorCode errorCode) {

@Override
public void run(FlowTrigger trigger, Map data) {
if (checkQemuLibvirtVersionOfHost()) {
trigger.next();
} else {
if (!checkQemuLibvirtVersionOfHost()) {
trigger.fail(operr("host [uuid:%s] cannot be added to cluster [uuid:%s] because qemu/libvirt version does not match",
self.getUuid(), self.getClusterUuid()));
return;
}

if (KVMGlobalConfig.CHECK_HOST_CPU_MODEL_NAME.value(Boolean.class) && !checkCpuModelOfHost()) {
trigger.fail(operr("host [uuid:%s] cannot be added to cluster [uuid:%s] because cpu model name does not match",
self.getUuid(), self.getClusterUuid()));
return;
}

trigger.next();
}
});
}
Expand Down Expand Up @@ -2811,6 +2837,35 @@ public void handle(Map data) {
}
}

private boolean checkCpuModelOfHost() {
List<String> hostUuidsInCluster = Q.New(HostVO.class)
.select(HostVO_.uuid)
.eq(HostVO_.clusterUuid, self.getClusterUuid())
.notEq(HostVO_.uuid, self.getUuid())
.listValues();
if (hostUuidsInCluster.isEmpty()) {
return true;
}

Map<String, List<String>> cpuModelNames = KVMSystemTags.CPU_MODEL_NAME.getTags(hostUuidsInCluster);
if (cpuModelNames != null && cpuModelNames.size() != 0) {
String clusterCpuModelName = KVMSystemTags.CPU_MODEL_NAME.getTokenByTag(
cpuModelNames.values().iterator().next().get(0),
KVMSystemTags.CPU_MODEL_NAME_TOKEN
);

String hostCpuModelName = KVMSystemTags.CPU_MODEL_NAME.getTokenByResourceUuid(
self.getUuid(), KVMSystemTags.CPU_MODEL_NAME_TOKEN
);

if (clusterCpuModelName != null && !clusterCpuModelName.equals(hostCpuModelName)) {
return false;
}
}

return true;
}

private boolean checkQemuLibvirtVersionOfHost() {
List<String> hostUuidsInCluster = Q.New(HostVO.class)
.select(HostVO_.uuid)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,23 +28,32 @@ public List<HostVO> filterHostCandidates(List<HostVO> candidates, HostAllocatorS
String srcHostUuid = spec.getVmInstance().getHostUuid();
String srcQemuVer = KVMSystemTags.QEMU_IMG_VERSION.getTokenByResourceUuid(srcHostUuid, KVMSystemTags.QEMU_IMG_VERSION_TOKEN);
String srcLibvirtVer = KVMSystemTags.LIBVIRT_VERSION.getTokenByResourceUuid(srcHostUuid, KVMSystemTags.LIBVIRT_VERSION_TOKEN);
String srcCpuModelName = KVMSystemTags.CPU_MODEL_NAME.getTokenByResourceUuid(srcHostUuid, KVMSystemTags.CPU_MODEL_NAME_TOKEN);

// nothing to check
if (srcQemuVer == null && srcLibvirtVer == null) {
if (srcQemuVer == null && srcLibvirtVer == null && srcCpuModelName == null) {
return candidates;
}

for (HostVO host : candidates) {
String dstQemuVer = KVMSystemTags.QEMU_IMG_VERSION.getTokenByResourceUuid(host.getUuid(), KVMSystemTags.QEMU_IMG_VERSION_TOKEN);
String dstLibvirtVer = KVMSystemTags.LIBVIRT_VERSION.getTokenByResourceUuid(host.getUuid(), KVMSystemTags.LIBVIRT_VERSION_TOKEN);
String dstCpuModelName = KVMSystemTags.CPU_MODEL_NAME.getTokenByResourceUuid(host.getUuid(), KVMSystemTags.CPU_MODEL_NAME_TOKEN);
if ((srcQemuVer == null || srcQemuVer.equals(dstQemuVer))
&& (srcLibvirtVer == null || srcLibvirtVer.equals(dstLibvirtVer))) {
result.add(host);
} else {
logger.debug(String.format("cannot migrate vm[uuid:%s] to host[uuid:%s] because qemu/libvirt version not match",
spec.getVmInstance().getUuid(), host.getUuid()));
}

if (KVMGlobalConfig.CHECK_HOST_CPU_MODEL_NAME.value(Boolean.class) && srcCpuModelName != null && !srcCpuModelName.equals(dstCpuModelName)) {
result.remove(host);
logger.debug(String.format("cannot migrate vm[uuid:%s] to host[uuid:%s] because cpu model name not match",
spec.getVmInstance().getUuid(), host.getUuid()));
}
}

return result;
}
}
3 changes: 3 additions & 0 deletions plugin/kvm/src/main/java/org/zstack/kvm/KVMSystemTags.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ public class KVMSystemTags {
public static final String HVM_CPU_FLAG_TOKEN = "flag";
public static PatternedSystemTag HVM_CPU_FLAG = new PatternedSystemTag(String.format("hvm::{%s}", HVM_CPU_FLAG_TOKEN), HostVO.class);

public static final String CPU_MODEL_NAME_TOKEN = "name";
public static PatternedSystemTag CPU_MODEL_NAME = new PatternedSystemTag(String.format("cpuModelName::{%s}", CPU_MODEL_NAME_TOKEN), HostVO.class);

public static SystemTag VIRTIO_SCSI = new SystemTag("capability:virtio-scsi", HostVO.class);

public static final String L2_BRIDGE_NAME_TOKEN = "name";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package org.zstack.test.integration.kvm.host
import org.zstack.core.Platform
import org.zstack.core.db.Q
import org.zstack.header.host.HostVO
import org.zstack.kvm.KVMGlobalConfig
import org.zstack.kvm.KVMSystemTags
import org.zstack.sdk.AddKVMHostAction
import org.zstack.sdk.ClusterInventory
Expand All @@ -14,8 +15,9 @@ import org.zstack.testlib.SubCase
import static org.zstack.utils.CollectionDSL.e
import static org.zstack.utils.CollectionDSL.map

class AddHostCheckQemuLibvirtCase extends SubCase {
class AddHostCheckQemuLibvirtCPUModelCase extends SubCase {
EnvSpec env
def cpuModelName = "Intel(R) Xeon(R) CPU E5-2630 v4 @ 2.20GHz"

@Override
void clean() {
Expand Down Expand Up @@ -45,7 +47,8 @@ class AddHostCheckQemuLibvirtCase extends SubCase {
password = "password"
systemTags = [
KVMSystemTags.QEMU_IMG_VERSION.instantiateTag(map(e(KVMSystemTags.QEMU_IMG_VERSION_TOKEN, "2.6.0"))),
KVMSystemTags.LIBVIRT_VERSION.instantiateTag(map(e(KVMSystemTags.LIBVIRT_VERSION_TOKEN, "1.3.3")))
KVMSystemTags.LIBVIRT_VERSION.instantiateTag(map(e(KVMSystemTags.LIBVIRT_VERSION_TOKEN, "1.3.3"))),
KVMSystemTags.CPU_MODEL_NAME.instantiateTag(map(e(KVMSystemTags.CPU_MODEL_NAME_TOKEN, cpuModelName)))
]
}

Expand All @@ -56,7 +59,8 @@ class AddHostCheckQemuLibvirtCase extends SubCase {
password = "password"
systemTags = [
KVMSystemTags.QEMU_IMG_VERSION.instantiateTag(map(e(KVMSystemTags.QEMU_IMG_VERSION_TOKEN, "2.6.0"))),
KVMSystemTags.LIBVIRT_VERSION.instantiateTag(map(e(KVMSystemTags.LIBVIRT_VERSION_TOKEN, "1.3.3")))
KVMSystemTags.LIBVIRT_VERSION.instantiateTag(map(e(KVMSystemTags.LIBVIRT_VERSION_TOKEN, "1.3.3"))),
KVMSystemTags.CPU_MODEL_NAME.instantiateTag(map(e(KVMSystemTags.CPU_MODEL_NAME_TOKEN, cpuModelName)))
]
}
}
Expand All @@ -69,6 +73,7 @@ class AddHostCheckQemuLibvirtCase extends SubCase {
env.create {
testAddHostWithDifferentQemuVerion()
testAddHostWithSameQemuVerion()
testAddHostCpuModelName()
}
}

Expand Down Expand Up @@ -115,4 +120,69 @@ class AddHostCheckQemuLibvirtCase extends SubCase {
uuid = host.uuid
}
}

void testAddHostCpuModelName() {
ClusterInventory cluster = env.inventoryByName("cluster-1") as ClusterInventory

updateGlobalConfig {
category = KVMGlobalConfig.CATEGORY
name = "checkHostCpuModelName"
value = true
}

AddKVMHostAction action = new AddKVMHostAction()
action.resourceUuid = Platform.getUuid()
action.sessionId = adminSession()
action.clusterUuid = cluster.uuid
action.name = "kvm13"
action.managementIp = "127.0.0.14"
action.username = "root"
action.password = "password"
action.systemTags = [
KVMSystemTags.QEMU_IMG_VERSION.instantiateTag(map(e(KVMSystemTags.QEMU_IMG_VERSION_TOKEN, "2.9.0"))),
KVMSystemTags.LIBVIRT_VERSION.instantiateTag(map(e(KVMSystemTags.LIBVIRT_VERSION_TOKEN, "1.3.3"))),
KVMSystemTags.CPU_MODEL_NAME.instantiateTag(map(e(KVMSystemTags.CPU_MODEL_NAME_TOKEN, "Intel(R)")))
]
def res = action.call()
assert res.error != null


action = new AddKVMHostAction()
action.resourceUuid = Platform.getUuid()
action.sessionId = adminSession()
action.clusterUuid = cluster.uuid
action.name = "kvm13"
action.managementIp = "127.0.0.14"
action.username = "root"
action.password = "password"
action.systemTags = [
KVMSystemTags.QEMU_IMG_VERSION.instantiateTag(map(e(KVMSystemTags.QEMU_IMG_VERSION_TOKEN, "2.6.0"))),
KVMSystemTags.LIBVIRT_VERSION.instantiateTag(map(e(KVMSystemTags.LIBVIRT_VERSION_TOKEN, "1.3.3"))),
KVMSystemTags.CPU_MODEL_NAME.instantiateTag(map(e(KVMSystemTags.CPU_MODEL_NAME_TOKEN, cpuModelName)))
]
res = action.call()
assert res.error == null

updateGlobalConfig {
category = KVMGlobalConfig.CATEGORY
name = "checkHostCpuModelName"
value = false
}

action = new AddKVMHostAction()
action.resourceUuid = Platform.getUuid()
action.sessionId = adminSession()
action.clusterUuid = cluster.uuid
action.name = "kvm13"
action.managementIp = "127.0.0.15"
action.username = "root"
action.password = "password"
action.systemTags = [
KVMSystemTags.QEMU_IMG_VERSION.instantiateTag(map(e(KVMSystemTags.QEMU_IMG_VERSION_TOKEN, "2.6.0"))),
KVMSystemTags.LIBVIRT_VERSION.instantiateTag(map(e(KVMSystemTags.LIBVIRT_VERSION_TOKEN, "1.3.3"))),
KVMSystemTags.CPU_MODEL_NAME.instantiateTag(map(e(KVMSystemTags.CPU_MODEL_NAME_TOKEN, "test cpu name")))
]
res = action.call()
assert res.error == null
}
}
Loading

0 comments on commit a6f3783

Please sign in to comment.