Report current CPUs in status.
This commit is contained in:
parent
7f512082f0
commit
8a7d9d6621
3 changed files with 86 additions and 27 deletions
|
|
@ -19,8 +19,8 @@
|
|||
package org.jdrupes.vmoperator.runner.qemu;
|
||||
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
|
|
@ -81,34 +81,28 @@ public class CpuController extends Component {
|
|||
/**
|
||||
* On monitor result.
|
||||
*
|
||||
* @param result the result
|
||||
* @param event the result
|
||||
*/
|
||||
@Handler
|
||||
public void onHotpluggableCpuStatus(HotpluggableCpuStatus result) {
|
||||
if (!result.successful()) {
|
||||
public void onHotpluggableCpuStatus(HotpluggableCpuStatus event) {
|
||||
if (!event.successful()) {
|
||||
logger.warning(() -> "Failed to get hotpluggable CPU status "
|
||||
+ "(won't adjust number of CPUs.): " + result.errorMessage());
|
||||
+ "(won't adjust number of CPUs.): " + event.errorMessage());
|
||||
}
|
||||
|
||||
// Sort
|
||||
List<ObjectNode> used = new ArrayList<>();
|
||||
List<ObjectNode> unused = new ArrayList<>();
|
||||
for (var itr = result.values().iterator(); itr.hasNext();) {
|
||||
ObjectNode cpu = (ObjectNode) itr.next();
|
||||
if (cpu.has("qom-path")) {
|
||||
used.add(cpu);
|
||||
} else {
|
||||
unused.add(cpu);
|
||||
}
|
||||
}
|
||||
currentCpus = used.size();
|
||||
if (desiredCpus == null) {
|
||||
return;
|
||||
}
|
||||
// Process
|
||||
int diff = used.size() - desiredCpus;
|
||||
diff = addCpus(used, unused, diff);
|
||||
deleteCpus(used, diff);
|
||||
currentCpus = event.usedCpus().size();
|
||||
int diff = currentCpus - desiredCpus;
|
||||
if (diff == 0) {
|
||||
return;
|
||||
}
|
||||
diff = addCpus(event.usedCpus(), event.unusedCpus(), diff);
|
||||
removeCpus(event.usedCpus(), diff);
|
||||
|
||||
// Report result
|
||||
fire(new MonitorCommand(new QmpQueryHotpluggableCpus()));
|
||||
}
|
||||
|
||||
@SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops")
|
||||
|
|
@ -123,22 +117,24 @@ public class CpuController extends Component {
|
|||
}
|
||||
}
|
||||
int nextId = 1;
|
||||
while (diff < 0 && !unused.isEmpty()) {
|
||||
List<ObjectNode> remaining = new LinkedList<>(unused);
|
||||
while (diff < 0 && !remaining.isEmpty()) {
|
||||
String id;
|
||||
do {
|
||||
id = "cpu-" + nextId++;
|
||||
} while (usedIds.contains(id));
|
||||
fire(new MonitorCommand(new QmpAddCpu(unused.get(0), id)));
|
||||
unused.remove(0);
|
||||
fire(new MonitorCommand(new QmpAddCpu(remaining.get(0), id)));
|
||||
remaining.remove(0);
|
||||
diff += 1;
|
||||
}
|
||||
return diff;
|
||||
}
|
||||
|
||||
@SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops")
|
||||
private int deleteCpus(List<ObjectNode> used, int diff) {
|
||||
while (diff > 0 && !used.isEmpty()) {
|
||||
ObjectNode cpu = used.remove(0);
|
||||
private int removeCpus(List<ObjectNode> used, int diff) {
|
||||
List<ObjectNode> removable = new LinkedList<>(used);
|
||||
while (diff > 0 && !removable.isEmpty()) {
|
||||
ObjectNode cpu = removable.remove(0);
|
||||
String qomPath = cpu.get("qom-path").asText();
|
||||
if (!qomPath.startsWith("/machine/peripheral/cpu-")) {
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ import java.util.Optional;
|
|||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import org.jdrupes.vmoperator.runner.qemu.events.BalloonChangeEvent;
|
||||
import org.jdrupes.vmoperator.runner.qemu.events.HotpluggableCpuStatus;
|
||||
import org.jdrupes.vmoperator.runner.qemu.events.RunnerConfigurationUpdate;
|
||||
import org.jdrupes.vmoperator.runner.qemu.events.RunnerStateChange;
|
||||
import org.jdrupes.vmoperator.runner.qemu.events.RunnerStateChange.State;
|
||||
|
|
@ -223,8 +224,10 @@ public class StatusUpdater extends Component {
|
|||
if (event.state() == State.STARTING) {
|
||||
status.addProperty("ram", GsonPtr.to(from.getRaw())
|
||||
.getAsString("spec", "vm", "maximumRam").orElse("0"));
|
||||
status.addProperty("cpus", 1);
|
||||
} else if (event.state() == State.STOPPED) {
|
||||
status.addProperty("ram", "0");
|
||||
status.addProperty("cpus", 0);
|
||||
}
|
||||
return status;
|
||||
});
|
||||
|
|
@ -273,4 +276,24 @@ public class StatusUpdater extends Component {
|
|||
return status;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* On ballon change.
|
||||
*
|
||||
* @param event the event
|
||||
* @throws ApiException
|
||||
*/
|
||||
@Handler
|
||||
public void onCpuChange(HotpluggableCpuStatus event) throws ApiException {
|
||||
if (vmCrApi == null) {
|
||||
return;
|
||||
}
|
||||
var vmCr
|
||||
= vmCrApi.get(namespace, vmName).throwsApiException().getObject();
|
||||
vmCrApi.updateStatus(vmCr, from -> {
|
||||
JsonObject status = currentStatus(from);
|
||||
status.addProperty("cpus", event.usedCpus().size());
|
||||
return status;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,6 +19,10 @@
|
|||
package org.jdrupes.vmoperator.runner.qemu.events;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import org.jdrupes.vmoperator.runner.qemu.commands.QmpCommand;
|
||||
|
||||
/**
|
||||
|
|
@ -26,6 +30,9 @@ import org.jdrupes.vmoperator.runner.qemu.commands.QmpCommand;
|
|||
*/
|
||||
public class HotpluggableCpuStatus extends MonitorResult {
|
||||
|
||||
private List<ObjectNode> usedCpus = new ArrayList<>();
|
||||
private List<ObjectNode> unusedCpus = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Instantiates a new hotpluggable cpu result.
|
||||
*
|
||||
|
|
@ -34,6 +41,39 @@ public class HotpluggableCpuStatus extends MonitorResult {
|
|||
*/
|
||||
public HotpluggableCpuStatus(QmpCommand command, JsonNode response) {
|
||||
super(command, response);
|
||||
if (!successful()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Sort
|
||||
for (var itr = values().iterator(); itr.hasNext();) {
|
||||
ObjectNode cpu = (ObjectNode) itr.next();
|
||||
if (cpu.has("qom-path")) {
|
||||
usedCpus.add(cpu);
|
||||
} else {
|
||||
unusedCpus.add(cpu);
|
||||
}
|
||||
}
|
||||
usedCpus = Collections.unmodifiableList(usedCpus);
|
||||
unusedCpus = Collections.unmodifiableList(unusedCpus);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the used cpus.
|
||||
*
|
||||
* @return the usedCpus
|
||||
*/
|
||||
public List<ObjectNode> usedCpus() {
|
||||
return usedCpus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the unused cpus.
|
||||
*
|
||||
* @return the unusedCpus
|
||||
*/
|
||||
public List<ObjectNode> unusedCpus() {
|
||||
return unusedCpus;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue