Merge branch 'main' into testing

This commit is contained in:
Michael Lipp 2025-03-15 12:37:12 +01:00
commit 7902ef7a7b
2 changed files with 27 additions and 9 deletions

View file

@ -3,10 +3,23 @@
![Latest Manager](https://img.shields.io/github/v/tag/mnlipp/vm-operator?filter=manager*&label=latest)
![Latest Runner](https://img.shields.io/github/v/tag/mnlipp/vm-operator?filter=runner-qemu*&label=latest)
# Run Qemu in Kubernetes Pods
# Run QEMU/KVM in Kubernetes Pods
The goal of this project is to provide simply to use and flexible components
for running Qemu based VMs in Kubernetes pods.
![Overview picture](webpages/index-pic.svg)
This project provides an easy to use and flexible solution for running
QEMU/KVM based VMs in Kubernetes pods.
The central component of this solution is the kubernetes operator that
manages "runners". These run in pods and are used to start and manage
the QEMU/KVM process for the VMs (optionally together with a SW-TPM).
A web GUI for administrators provides an overview of the VMs together
with some basic control over the VMs. A web GUI for users provides an
interface to access and optionally start, stop and reset the VMs.
Advanced features of the operator include pooling of VMs and automatic
login.
See the [project's home page](https://vm-operator.jdrupes.org/)
for details.

View file

@ -125,16 +125,19 @@ public class VmDefUpdater extends Component {
protected JsonObject updateCondition(VmDefinition from, String type,
boolean state, String reason, String message) {
JsonObject status = from.statusJson();
// Optimize, as we can get this several times
// Avoid redundant updates, as this may be called several times
var current = status.getAsJsonArray("conditions").asList().stream()
.map(cond -> (JsonObject) cond)
.filter(cond -> type.equals(cond.get("type").getAsString()))
.findFirst();
if (current.isPresent()
&& current.map(c -> c.get("status").getAsString())
.map("True"::equals).map(s -> s == state).orElse(false)
var stateUnchanged = current.map(c -> c.get("status").getAsString())
.map("True"::equals).map(s -> s == state).orElse(false);
if (stateUnchanged
&& current.map(c -> c.get("reason").getAsString())
.map(reason::equals).orElse(false)) {
.map(reason::equals).orElse(false)
&& current.map(c -> c.get("observedGeneration").getAsLong())
.map(from.getMetadata().getGeneration()::equals)
.orElse(false)) {
return status;
}
@ -143,7 +146,9 @@ public class VmDefUpdater extends Component {
"status", state ? "True" : "False",
"observedGeneration", from.getMetadata().getGeneration(),
"reason", reason,
"lastTransitionTime", Instant.now().toString()));
"lastTransitionTime", stateUnchanged
? current.get().get("lastTransitionTime").getAsString()
: Instant.now().toString()));
if (message != null) {
condition.put("message", message);
}