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 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) ![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 ![Overview picture](webpages/index-pic.svg)
for running Qemu based VMs in Kubernetes pods.
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/) See the [project's home page](https://vm-operator.jdrupes.org/)
for details. for details.

View file

@ -125,16 +125,19 @@ public class VmDefUpdater extends Component {
protected JsonObject updateCondition(VmDefinition from, String type, protected JsonObject updateCondition(VmDefinition from, String type,
boolean state, String reason, String message) { boolean state, String reason, String message) {
JsonObject status = from.statusJson(); 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() var current = status.getAsJsonArray("conditions").asList().stream()
.map(cond -> (JsonObject) cond) .map(cond -> (JsonObject) cond)
.filter(cond -> type.equals(cond.get("type").getAsString())) .filter(cond -> type.equals(cond.get("type").getAsString()))
.findFirst(); .findFirst();
if (current.isPresent() var stateUnchanged = current.map(c -> c.get("status").getAsString())
&& current.map(c -> c.get("status").getAsString()) .map("True"::equals).map(s -> s == state).orElse(false);
.map("True"::equals).map(s -> s == state).orElse(false) if (stateUnchanged
&& current.map(c -> c.get("reason").getAsString()) && 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; return status;
} }
@ -143,7 +146,9 @@ public class VmDefUpdater extends Component {
"status", state ? "True" : "False", "status", state ? "True" : "False",
"observedGeneration", from.getMetadata().getGeneration(), "observedGeneration", from.getMetadata().getGeneration(),
"reason", reason, "reason", reason,
"lastTransitionTime", Instant.now().toString())); "lastTransitionTime", stateUnchanged
? current.get().get("lastTransitionTime").getAsString()
: Instant.now().toString()));
if (message != null) { if (message != null) {
condition.put("message", message); condition.put("message", message);
} }