From 04ccdd7dee7c463258787d1237939ce86f1a9133 Mon Sep 17 00:00:00 2001 From: "Michael N. Lipp" Date: Tue, 4 Mar 2025 21:35:36 +0100 Subject: [PATCH] Add condition for logged in state. --- deploy/crds/vms-crd.yaml | 18 +++++++++ .../jdrupes/vmoperator/common/Constants.java | 15 +++++++ .../vmoperator/runner/qemu/StatusUpdater.java | 40 ++++++++++++++++--- .../vmoperator/runner/qemu/VmDefUpdater.java | 9 +++-- 4 files changed, 74 insertions(+), 8 deletions(-) diff --git a/deploy/crds/vms-crd.yaml b/deploy/crds/vms-crd.yaml index 2a14f0c..101784f 100644 --- a/deploy/crds/vms-crd.yaml +++ b/deploy/crds/vms-crd.yaml @@ -1534,6 +1534,24 @@ spec: lastTransitionTime: "1970-01-01T00:00:00Z" reason: Creation message: "Creation of CR" + - type: Booted + status: "False" + observedGeneration: 1 + lastTransitionTime: "1970-01-01T00:00:00Z" + reason: Creation + message: "Creation of CR" + - type: VmopAgentConnected + status: "False" + observedGeneration: 1 + lastTransitionTime: "1970-01-01T00:00:00Z" + reason: Creation + message: "Creation of CR" + - type: UserLoggedIn + status: "False" + observedGeneration: 1 + lastTransitionTime: "1970-01-01T00:00:00Z" + reason: Creation + message: "Creation of CR" - type: ConsoleConnected status: "False" observedGeneration: 1 diff --git a/org.jdrupes.vmoperator.common/src/org/jdrupes/vmoperator/common/Constants.java b/org.jdrupes.vmoperator.common/src/org/jdrupes/vmoperator/common/Constants.java index 71c8cf3..0d9657a 100644 --- a/org.jdrupes.vmoperator.common/src/org/jdrupes/vmoperator/common/Constants.java +++ b/org.jdrupes.vmoperator.common/src/org/jdrupes/vmoperator/common/Constants.java @@ -74,6 +74,21 @@ public class Constants { /** The Constant ASSIGNMENT. */ public static final String ASSIGNMENT = "assignment"; + + /** The Constant COND_RUNNING. */ + public static final String COND_RUNNING = "Running"; + + /** The Constant COND_BOOTED. */ + public static final String COND_BOOTED = "Booted"; + + /** The Constant COND_VMOP_AGENT. */ + public static final String COND_VMOP_AGENT = "VmopAgentConnected"; + + /** The Constant COND_USER_LOGGED_IN. */ + public static final String COND_USER_LOGGED_IN = "UserLoggedIn"; + + /** The Constant COND_CONSOLE. */ + public static final String COND_CONSOLE = "ConsoleConnected"; } /** diff --git a/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/StatusUpdater.java b/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/StatusUpdater.java index 36a63c1..d983311 100644 --- a/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/StatusUpdater.java +++ b/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/StatusUpdater.java @@ -72,6 +72,7 @@ public class StatusUpdater extends VmDefUpdater { private boolean guestShutdownStops; private boolean shutdownByGuest; private VmDefinitionStub vmStub; + private String loggedInUser; /** * Instantiates a new status updater. @@ -143,6 +144,7 @@ public class StatusUpdater extends VmDefUpdater { public void onConfigureQemu(ConfigureQemu event) throws ApiException { guestShutdownStops = event.configuration().guestShutdownStops; + loggedInUser = event.configuration().vm.display.loggedInUser; // Remainder applies only if we have a connection to k8s. if (vmStub == null) { @@ -169,10 +171,12 @@ public class StatusUpdater extends VmDefUpdater { status.addProperty(Status.DISPLAY_PASSWORD_SERIAL, -1); } status.getAsJsonArray("conditions").asList().stream() - .map(cond -> (JsonObject) cond).filter(cond -> "Running" + .map(cond -> (JsonObject) cond) + .filter(cond -> Status.COND_RUNNING .equals(cond.get("type").getAsString())) .forEach(cond -> cond.addProperty("observedGeneration", from.getMetadata().getGeneration())); + updateUserLoggedIn(from); return status; }, vmDef); } @@ -194,9 +198,9 @@ public class StatusUpdater extends VmDefUpdater { } vmStub.updateStatus(from -> { boolean running = event.runState().vmRunning(); - updateCondition(vmDef, "Running", running, event.reason(), + updateCondition(vmDef, Status.COND_RUNNING, running, event.reason(), event.message()); - JsonObject status = updateCondition(vmDef, "Booted", + JsonObject status = updateCondition(vmDef, Status.COND_BOOTED, event.runState() == RunState.BOOTED, event.reason(), event.message()); if (event.runState() == RunState.STARTING) { @@ -212,10 +216,12 @@ public class StatusUpdater extends VmDefUpdater { if (!running) { // In case console connection was still present status.addProperty(Status.CONSOLE_CLIENT, ""); - updateCondition(from, "ConsoleConnected", false, "VmStopped", + updateCondition(from, Status.COND_CONSOLE, false, "VmStopped", "The VM is not running"); // In case we had an irregular shutdown + updateCondition(from, Status.COND_USER_LOGGED_IN, false, + "VmStopped", "The VM is not running"); status.remove(Status.OSINFO); updateCondition(vmDef, "VmopAgentConnected", false, "VmStopped", "The VM is not running"); @@ -245,6 +251,26 @@ public class StatusUpdater extends VmDefUpdater { K8s.createEvent(apiClient, vmDef, evt); } + private void updateUserLoggedIn(VmDefinition from) { + if (loggedInUser == null) { + updateCondition(from, Status.COND_USER_LOGGED_IN, false, + "NotRequested", "No user to be logged in"); + return; + } + if (!from.conditionStatus(Status.COND_VMOP_AGENT).orElse(false)) { + updateCondition(from, Status.COND_USER_LOGGED_IN, false, + "VmopAgentDisconnected", "Waiting for VMOP agent to connect"); + return; + } + if (!from.fromStatus(Status.LOGGED_IN_USER).map(loggedInUser::equals) + .orElse(false)) { + updateCondition(from, Status.COND_USER_LOGGED_IN, false, + "Processing", "Waiting for user to be logged in"); + } + updateCondition(from, Status.COND_USER_LOGGED_IN, true, + "UserLoggedIn", "User is logged in"); + } + /** * On ballon change. * @@ -348,8 +374,10 @@ public class StatusUpdater extends VmDefUpdater { return; } vmStub.updateStatus(from -> { - return updateCondition(vmDef, "VmopAgentConnected", + var status = updateCondition(vmDef, "VmopAgentConnected", true, "VmopAgentStarted", "The VM operator agent is running"); + updateUserLoggedIn(from); + return status; }, vmDef); } @@ -365,6 +393,7 @@ public class StatusUpdater extends VmDefUpdater { JsonObject status = from.statusJson(); status.addProperty(Status.LOGGED_IN_USER, event.triggering().user()); + updateUserLoggedIn(from); return status; }); } @@ -380,6 +409,7 @@ public class StatusUpdater extends VmDefUpdater { vmStub.updateStatus(from -> { JsonObject status = from.statusJson(); status.remove(Status.LOGGED_IN_USER); + updateUserLoggedIn(from); return status; }); } diff --git a/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/VmDefUpdater.java b/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/VmDefUpdater.java index 50017c1..4c64ff1 100644 --- a/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/VmDefUpdater.java +++ b/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/VmDefUpdater.java @@ -129,9 +129,12 @@ public class VmDefUpdater extends Component { var current = status.getAsJsonArray("conditions").asList().stream() .map(cond -> (JsonObject) cond) .filter(cond -> type.equals(cond.get("type").getAsString())) - .findFirst() - .map(cond -> "True".equals(cond.get("status").getAsString())); - if (current.isPresent() && current.get() == state) { + .findFirst(); + if (current.isPresent() + && current.map(c -> c.get("status").getAsString()) + .map("True"::equals).map(s -> s == state).orElse(false) + && current.map(c -> c.get("reason").getAsString()) + .map(reason::equals).orElse(false)) { return status; }