Skip to content

Commit 687a21c

Browse files
committed
Merge remote-tracking branch 'apache/4.17' into main
2 parents 65c7070 + b831f23 commit 687a21c

File tree

5 files changed

+94
-24
lines changed

5 files changed

+94
-24
lines changed

plugins/hypervisors/kvm/src/main/java/org/apache/cloudstack/utils/linux/KVMHostInfo.java

Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,33 @@
1616
// under the License.
1717
package org.apache.cloudstack.utils.linux;
1818

19-
import com.cloud.hypervisor.kvm.resource.LibvirtCapXMLParser;
20-
import com.cloud.hypervisor.kvm.resource.LibvirtConnection;
21-
import com.cloud.utils.script.Script;
19+
import java.io.FileReader;
20+
import java.io.IOException;
21+
import java.io.Reader;
22+
import java.io.StringReader;
23+
import java.util.ArrayList;
24+
import java.util.List;
2225

26+
import javax.xml.parsers.DocumentBuilder;
27+
import javax.xml.parsers.DocumentBuilderFactory;
28+
29+
import org.apache.cloudstack.utils.security.ParserUtils;
2330
import org.apache.commons.io.IOUtils;
31+
import org.apache.commons.lang3.StringUtils;
2432
import org.apache.log4j.Logger;
2533
import org.libvirt.Connect;
2634
import org.libvirt.LibvirtException;
2735
import org.libvirt.NodeInfo;
36+
import org.w3c.dom.Document;
37+
import org.w3c.dom.Element;
38+
import org.w3c.dom.NamedNodeMap;
39+
import org.w3c.dom.Node;
40+
import org.w3c.dom.NodeList;
41+
import org.xml.sax.InputSource;
2842

29-
import java.io.FileReader;
30-
import java.io.IOException;
31-
import java.io.Reader;
32-
import java.util.ArrayList;
33-
import java.util.List;
43+
import com.cloud.hypervisor.kvm.resource.LibvirtCapXMLParser;
44+
import com.cloud.hypervisor.kvm.resource.LibvirtConnection;
45+
import com.cloud.utils.script.Script;
3446

3547
public class KVMHostInfo {
3648

@@ -82,7 +94,7 @@ public List<String> getCapabilities() {
8294
return this.capabilities;
8395
}
8496

85-
protected static long getCpuSpeed(final NodeInfo nodeInfo) {
97+
protected static long getCpuSpeed(final String cpabilities, final NodeInfo nodeInfo) {
8698
long speed = 0L;
8799
speed = getCpuSpeedFromCommandLscpu();
88100
if(speed > 0L) {
@@ -94,6 +106,11 @@ protected static long getCpuSpeed(final NodeInfo nodeInfo) {
94106
return speed;
95107
}
96108

109+
speed = getCpuSpeedFromHostCapabilities(cpabilities);
110+
if(speed > 0L) {
111+
return speed;
112+
}
113+
97114
LOGGER.info(String.format("Using the value [%s] provided by Libvirt.", nodeInfo.mhz));
98115
speed = nodeInfo.mhz;
99116
return speed;
@@ -125,12 +142,41 @@ private static long getCpuSpeedFromFile() {
125142
}
126143
}
127144

145+
protected static long getCpuSpeedFromHostCapabilities(final String capabilities) {
146+
LOGGER.info("Fetching CPU speed from \"host capabilities\"");
147+
long speed = 0L;
148+
try {
149+
DocumentBuilderFactory docFactory = ParserUtils.getSaferDocumentBuilderFactory();
150+
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
151+
Document doc = docBuilder.parse(new InputSource(new StringReader(capabilities)));
152+
Element rootElement = doc.getDocumentElement();
153+
NodeList nodes = rootElement.getElementsByTagName("cpu");
154+
Node node = nodes.item(0);
155+
nodes = ((Element)node).getElementsByTagName("counter");
156+
for (int i = 0; i < nodes.getLength(); i++) {
157+
node = nodes.item(i);
158+
NamedNodeMap attributes = node.getAttributes();
159+
Node nameNode = attributes.getNamedItem("name");
160+
Node freqNode = attributes.getNamedItem("frequency");
161+
if (nameNode != null && "tsc".equals(nameNode.getNodeValue()) && freqNode != null && StringUtils.isNotEmpty(freqNode.getNodeValue())) {
162+
speed = Long.parseLong(freqNode.getNodeValue()) / 1000000;
163+
LOGGER.info(String.format("Retrieved value [%s] from \"host capabilities\". This corresponds to a CPU speed of [%s] MHz.", freqNode.getNodeValue(), speed));
164+
}
165+
}
166+
} catch (Exception ex) {
167+
LOGGER.error("Unable to fetch CPU speed from \"host capabilities\"", ex);
168+
speed = 0L;
169+
}
170+
return speed;
171+
}
172+
128173
private void getHostInfoFromLibvirt() {
129174
try {
130175
final Connect conn = LibvirtConnection.getConnection();
131176
final NodeInfo hosts = conn.nodeInfo();
177+
final String capabilities = conn.getCapabilities();
132178
if (this.cpuSpeed == 0) {
133-
this.cpuSpeed = getCpuSpeed(hosts);
179+
this.cpuSpeed = getCpuSpeed(capabilities, hosts);
134180
} else {
135181
LOGGER.debug(String.format("Using existing configured CPU frequency %s", this.cpuSpeed));
136182
}
@@ -146,7 +192,7 @@ private void getHostInfoFromLibvirt() {
146192
this.cpus = hosts.cpus;
147193

148194
final LibvirtCapXMLParser parser = new LibvirtCapXMLParser();
149-
parser.parseCapabilitiesXML(conn.getCapabilities());
195+
parser.parseCapabilitiesXML(capabilities);
150196
final ArrayList<String> oss = parser.getGuestOsType();
151197
for (final String s : oss) {
152198
/*

plugins/hypervisors/kvm/src/test/java/org/apache/cloudstack/utils/linux/KVMHostInfoTest.java

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,23 +16,22 @@
1616
// under the License.
1717
package org.apache.cloudstack.utils.linux;
1818

19-
import com.cloud.hypervisor.kvm.resource.LibvirtConnection;
2019
import org.apache.commons.lang.SystemUtils;
21-
2220
import org.hamcrest.Matchers;
23-
import org.junit.Test;
24-
import org.junit.Assume;
2521
import org.junit.Assert;
22+
import org.junit.Assume;
23+
import org.junit.Test;
2624
import org.junit.runner.RunWith;
2725
import org.libvirt.Connect;
28-
import org.mockito.Mockito;
29-
3026
import org.libvirt.NodeInfo;
27+
import org.mockito.Mockito;
3128
import org.powermock.api.mockito.PowerMockito;
3229
import org.powermock.core.classloader.annotations.PowerMockIgnore;
3330
import org.powermock.core.classloader.annotations.PrepareForTest;
3431
import org.powermock.modules.junit4.PowerMockRunner;
3532

33+
import com.cloud.hypervisor.kvm.resource.LibvirtConnection;
34+
3635
@RunWith(PowerMockRunner.class)
3736
@PrepareForTest(value = {LibvirtConnection.class})
3837
@PowerMockIgnore({"javax.xml.*", "org.w3c.dom.*", "org.apache.xerces.*", "org.xml.*"})
@@ -45,7 +44,21 @@ public void getCpuSpeed() {
4544
Assume.assumeTrue(SystemUtils.IS_OS_LINUX);
4645
NodeInfo nodeInfo = Mockito.mock(NodeInfo.class);
4746
nodeInfo.mhz = 1000;
48-
Assert.assertThat(KVMHostInfo.getCpuSpeed(nodeInfo), Matchers.greaterThan(0l));
47+
Assert.assertThat(KVMHostInfo.getCpuSpeed(null, nodeInfo), Matchers.greaterThan(0l));
48+
}
49+
50+
@Test
51+
public void getCpuSpeedFromHostCapabilities() {
52+
String capabilities = "<host>\n" +
53+
"<uuid>8a330742-345f-b0df-7954-c9960b88116c</uuid>\n" +
54+
" <cpu>\n" +
55+
" <arch>x86_64</arch>\n" +
56+
" <model>Opteron_G2</model>\n" +
57+
" <vendor>AMD</vendor>\n" +
58+
" <counter name='tsc' frequency='2350000000' scaling='no'/>\n" +
59+
" </cpu>\n" +
60+
"</host>\n";;
61+
Assert.assertEquals(2350L, KVMHostInfo.getCpuSpeedFromHostCapabilities(capabilities));
4962
}
5063

5164
@Test

pom.xml

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,20 @@
623623
<groupId>org.opensaml</groupId>
624624
<artifactId>opensaml</artifactId>
625625
<version>${cs.opensaml.version}</version>
626+
<exclusions>
627+
<exclusion>
628+
<groupId>org.slf4j</groupId>
629+
<artifactId>jcl-over-slf4j</artifactId>
630+
</exclusion>
631+
<exclusion>
632+
<groupId>org.slf4j</groupId>
633+
<artifactId>jul-to-slf4j</artifactId>
634+
</exclusion>
635+
<exclusion>
636+
<groupId>org.slf4j</groupId>
637+
<artifactId>log4j-over-slf4j</artifactId>
638+
</exclusion>
639+
</exclusions>
626640
</dependency>
627641
<dependency>
628642
<groupId>org.owasp.esapi</groupId>

server/src/main/java/com/cloud/configuration/ConfigurationManagerImpl.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4640,7 +4640,7 @@ public Vlan createVlanAndPublicIpRange(final long zoneId, final long networkId,
46404640
}
46414641
if (!StringUtils.isAllEmpty(ipv6Range, vlan.getIp6Range())) {
46424642
String r1 = StringUtils.isEmpty(ipv6Range) ? NetUtils.getIpv6RangeFromCidr(vlanIp6Cidr) : ipv6Range;
4643-
String r2 = StringUtils.isEmpty(vlan.getIp6Range()) ? NetUtils.getIpv6RangeFromCidr(vlanIp6Cidr) : vlan.getIp6Range();
4643+
String r2 = StringUtils.isEmpty(vlan.getIp6Range()) ? NetUtils.getIpv6RangeFromCidr(vlan.getIp6Cidr()) : vlan.getIp6Range();
46444644
if(NetUtils.isIp6RangeOverlap(r1, r2)) {
46454645
throw new InvalidParameterValueException(String.format("The IPv6 range with tag: %s already has IPs that overlap with the new range.",
46464646
vlan.getVlanTag()));

ui/src/views/infra/network/IpRangesTabPublic.vue

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@
239239
</div>
240240
<div class="form__item" v-if="!basicGuestNetwork && form.iptype != 'ip6'">
241241
<div style="color: black;">{{ $t('label.set.reservation') }}</div>
242-
<a-switch @change="handleShowAccountFields" />
242+
<a-switch v-model:checked="showAccountFields" @change="handleShowAccountFields" />
243243
</div>
244244
<div v-if="showAccountFields && !basicGuestNetwork" style="margin-top: 20px;">
245245
<div v-html="$t('label.set.reservation.desc')"></div>
@@ -555,12 +555,9 @@ export default {
555555
this.fetchDomains()
556556
},
557557
handleShowAccountFields () {
558-
if (this.showAccountFields === false) {
559-
this.showAccountFields = true
558+
if (this.showAccountFields) {
560559
this.fetchDomains()
561-
return
562560
}
563-
this.showAccountFields = false
564561
},
565562
handleOpenAddIpRangeModal () {
566563
this.initAddIpRangeForm()

0 commit comments

Comments
 (0)