Add booted state.
This commit is contained in:
parent
e4bba582a0
commit
ec8152bd51
4 changed files with 70 additions and 33 deletions
|
|
@ -33,7 +33,6 @@ import java.util.logging.Level;
|
|||
import org.jdrupes.vmoperator.runner.qemu.commands.QmpCommand;
|
||||
import org.jdrupes.vmoperator.runner.qemu.commands.QmpGuestGetOsinfo;
|
||||
import org.jdrupes.vmoperator.runner.qemu.events.GuestAgentCommand;
|
||||
import org.jdrupes.vmoperator.runner.qemu.events.MonitorReady;
|
||||
import org.jdrupes.vmoperator.runner.qemu.events.OsinfoEvent;
|
||||
import org.jdrupes.vmoperator.runner.qemu.events.VserportChangeEvent;
|
||||
import org.jgrapes.core.Channel;
|
||||
|
|
@ -188,10 +187,6 @@ public class GuestAgentClient extends Component {
|
|||
logger.fine(() -> "guest agent(in): " + line);
|
||||
try {
|
||||
var response = mapper.readValue(line, ObjectNode.class);
|
||||
if (response.has("QMP")) {
|
||||
rep.fire(new MonitorReady());
|
||||
return;
|
||||
}
|
||||
if (response.has("return") || response.has("error")) {
|
||||
QmpCommand executed = executing.poll();
|
||||
logger.fine(
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ import org.jdrupes.vmoperator.runner.qemu.commands.QmpReset;
|
|||
import org.jdrupes.vmoperator.runner.qemu.events.ConfigureQemu;
|
||||
import org.jdrupes.vmoperator.runner.qemu.events.Exit;
|
||||
import org.jdrupes.vmoperator.runner.qemu.events.MonitorCommand;
|
||||
import org.jdrupes.vmoperator.runner.qemu.events.OsinfoEvent;
|
||||
import org.jdrupes.vmoperator.runner.qemu.events.QmpConfigured;
|
||||
import org.jdrupes.vmoperator.runner.qemu.events.RunnerStateChange;
|
||||
import org.jdrupes.vmoperator.runner.qemu.events.RunnerStateChange.RunState;
|
||||
|
|
@ -619,7 +620,7 @@ public class Runner extends Component {
|
|||
}
|
||||
|
||||
/**
|
||||
* On monitor ready.
|
||||
* When the monitor is ready, send QEMU its initial configuration.
|
||||
*
|
||||
* @param event the event
|
||||
*/
|
||||
|
|
@ -629,28 +630,14 @@ public class Runner extends Component {
|
|||
}
|
||||
|
||||
/**
|
||||
* On configure qemu.
|
||||
*
|
||||
* @param event the event
|
||||
*/
|
||||
@Handler(priority = -1000)
|
||||
public void onConfigureQemuFinal(ConfigureQemu event) {
|
||||
if (state == RunState.STARTING) {
|
||||
fire(new MonitorCommand(new QmpCont()));
|
||||
state = RunState.RUNNING;
|
||||
rep.fire(new RunnerStateChange(state, "VmStarted",
|
||||
"Qemu has been configured and is continuing"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On configure qemu.
|
||||
* Whenever a new QEMU configuration is available, check if it
|
||||
* is supposed to trigger a reset.
|
||||
*
|
||||
* @param event the event
|
||||
*/
|
||||
@Handler
|
||||
public void onConfigureQemu(ConfigureQemu event) {
|
||||
if (state == RunState.RUNNING) {
|
||||
if (state.vmActive()) {
|
||||
if (resetCounter != null
|
||||
&& event.configuration().resetCounter != null
|
||||
&& event.configuration().resetCounter > resetCounter) {
|
||||
|
|
@ -660,6 +647,36 @@ public class Runner extends Component {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* As last step when handling a new configuration, check if
|
||||
* QEMU is suspended after startup and should be continued.
|
||||
*
|
||||
* @param event the event
|
||||
*/
|
||||
@Handler(priority = -1000)
|
||||
public void onConfigureQemuFinal(ConfigureQemu event) {
|
||||
if (state == RunState.STARTING) {
|
||||
state = RunState.BOOTING;
|
||||
fire(new MonitorCommand(new QmpCont()));
|
||||
rep.fire(new RunnerStateChange(state, "VmStarted",
|
||||
"Qemu has been configured and is continuing"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Receiving the OSinfo means that the OS has been booted.
|
||||
*
|
||||
* @param event the event
|
||||
*/
|
||||
@Handler
|
||||
public void onOsinfo(OsinfoEvent event) {
|
||||
if (state == RunState.BOOTING) {
|
||||
state = RunState.BOOTED;
|
||||
rep.fire(new RunnerStateChange(state, "VmBooted",
|
||||
"The VM has started the guest agent."));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On process exited.
|
||||
*
|
||||
|
|
@ -675,6 +692,7 @@ public class Runner extends Component {
|
|||
mayBeStartQemu(QemuPreps.CloudInit);
|
||||
return;
|
||||
}
|
||||
|
||||
// No other process(es) may exit during startup
|
||||
if (state == RunState.STARTING) {
|
||||
logger.severe(() -> "Process " + procDef.name
|
||||
|
|
@ -683,7 +701,9 @@ public class Runner extends Component {
|
|||
rep.fire(new Stop());
|
||||
return;
|
||||
}
|
||||
if (procDef.equals(qemuDefinition) && state == RunState.RUNNING) {
|
||||
|
||||
// No processes may exit while the VM is running normally
|
||||
if (procDef.equals(qemuDefinition) && state.vmActive()) {
|
||||
rep.fire(new Exit(event.exitValue()));
|
||||
}
|
||||
logger.info(() -> "Process " + procDef.name
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* VM-Operator
|
||||
* Copyright (C) 2023,2024 Michael N. Lipp
|
||||
* Copyright (C) 2023,2025 Michael N. Lipp
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
|
|
@ -31,7 +31,6 @@ import io.kubernetes.client.openapi.JSON;
|
|||
import io.kubernetes.client.openapi.models.EventsV1Event;
|
||||
import java.io.IOException;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import static org.jdrupes.vmoperator.common.Constants.APP_NAME;
|
||||
import static org.jdrupes.vmoperator.common.Constants.VM_OP_GROUP;
|
||||
|
|
@ -66,9 +65,6 @@ public class StatusUpdater extends VmDefUpdater {
|
|||
private static final ObjectMapper objectMapper
|
||||
= new ObjectMapper().registerModule(new JavaTimeModule());
|
||||
|
||||
private static final Set<RunState> RUNNING_STATES
|
||||
= Set.of(RunState.RUNNING, RunState.TERMINATING);
|
||||
|
||||
private long observedGeneration;
|
||||
private boolean guestShutdownStops;
|
||||
private boolean shutdownByGuest;
|
||||
|
|
@ -186,16 +182,23 @@ public class StatusUpdater extends VmDefUpdater {
|
|||
}
|
||||
vmStub.updateStatus(vmDef, from -> {
|
||||
JsonObject status = from.statusJson();
|
||||
boolean running = RUNNING_STATES.contains(event.runState());
|
||||
boolean running = event.runState().vmRunning();
|
||||
updateCondition(vmDef, vmDef.statusJson(), "Running", running,
|
||||
event.reason(), event.message());
|
||||
updateCondition(vmDef, vmDef.statusJson(), "Booted",
|
||||
event.runState() == RunState.BOOTED, event.reason(),
|
||||
event.message());
|
||||
if (event.runState() == RunState.STARTING) {
|
||||
status.addProperty("ram", GsonPtr.to(from.data())
|
||||
.getAsString("spec", "vm", "maximumRam").orElse("0"));
|
||||
status.addProperty("cpus", 1);
|
||||
|
||||
// In case we had an irregular shutdown
|
||||
status.remove("osinfo");
|
||||
} else if (event.runState() == RunState.STOPPED) {
|
||||
status.addProperty("ram", "0");
|
||||
status.addProperty("cpus", 0);
|
||||
status.remove("osinfo");
|
||||
}
|
||||
|
||||
// In case console connection was still present
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
package org.jdrupes.vmoperator.runner.qemu.events;
|
||||
|
||||
import java.util.EnumSet;
|
||||
import org.jgrapes.core.Channel;
|
||||
import org.jgrapes.core.Components;
|
||||
import org.jgrapes.core.Event;
|
||||
|
|
@ -29,10 +30,28 @@ import org.jgrapes.core.Event;
|
|||
public class RunnerStateChange extends Event<Void> {
|
||||
|
||||
/**
|
||||
* The state.
|
||||
* The states.
|
||||
*/
|
||||
public enum RunState {
|
||||
INITIALIZING, STARTING, RUNNING, TERMINATING, STOPPED
|
||||
INITIALIZING, STARTING, BOOTING, BOOTED, TERMINATING, STOPPED;
|
||||
|
||||
/**
|
||||
* Checks if the state is one of the states in which the VM is running.
|
||||
*
|
||||
* @return true, if is running
|
||||
*/
|
||||
public boolean vmRunning() {
|
||||
return EnumSet.of(BOOTING, BOOTED, TERMINATING).contains(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the state is one of the states in which the VM is active.
|
||||
*
|
||||
* @return true, if is active
|
||||
*/
|
||||
public boolean vmActive() {
|
||||
return EnumSet.of(BOOTING, BOOTED).contains(this);
|
||||
}
|
||||
}
|
||||
|
||||
private final RunState state;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue