Merge branch 'main' into release/v3.4.x
This commit is contained in:
commit
c69a658b72
8 changed files with 37 additions and 34 deletions
|
|
@ -17,7 +17,7 @@ dependencies {
|
|||
implementation 'org.jgrapes:org.jgrapes.io:[2.12.1,3)'
|
||||
implementation 'org.jgrapes:org.jgrapes.http:[3.5.0,4)'
|
||||
|
||||
implementation 'org.jgrapes:org.jgrapes.webconsole.base:[1.8.0,2)'
|
||||
implementation 'org.jgrapes:org.jgrapes.webconsole.base:[2.1.0,3)'
|
||||
implementation 'org.jgrapes:org.jgrapes.webconsole.vuejs:[1.5.0,2)'
|
||||
implementation 'org.jgrapes:org.jgrapes.webconsole.rbac:[1.4.0,2)'
|
||||
implementation 'org.jgrapes:org.jgrapes.webconlet.oidclogin:[1.7.0,2)'
|
||||
|
|
|
|||
|
|
@ -3,22 +3,18 @@ package org.jdrupes.vmoperator.manager;
|
|||
import io.kubernetes.client.Discovery.APIResource;
|
||||
import io.kubernetes.client.openapi.ApiException;
|
||||
import io.kubernetes.client.util.generic.options.ListOptions;
|
||||
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jdrupes.vmoperator.common.Constants.APP_NAME;
|
||||
import static org.jdrupes.vmoperator.common.Constants.VM_OP_GROUP;
|
||||
import static org.jdrupes.vmoperator.common.Constants.VM_OP_KIND_VM;
|
||||
import static org.jdrupes.vmoperator.common.Constants.VM_OP_NAME;
|
||||
|
||||
import org.jdrupes.vmoperator.common.K8s;
|
||||
import org.jdrupes.vmoperator.common.K8sClient;
|
||||
import org.jdrupes.vmoperator.common.K8sDynamicStub;
|
||||
import org.jdrupes.vmoperator.common.K8sV1ConfigMapStub;
|
||||
import org.jdrupes.vmoperator.common.K8sV1DeploymentStub;
|
||||
import org.jdrupes.vmoperator.common.K8sV1PodStub;
|
||||
import org.jdrupes.vmoperator.common.K8sV1PvcStub;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
|
|
|||
|
|
@ -238,6 +238,8 @@ public class QemuMonitor extends Component {
|
|||
* @param event the event
|
||||
*/
|
||||
@Handler
|
||||
@SuppressWarnings({ "PMD.AvoidSynchronizedStatement",
|
||||
"PMD.AvoidDuplicateLiterals" })
|
||||
public void onClosed(Closed<?> event, SocketIOChannel channel) {
|
||||
channel.associated(QemuMonitor.class).ifPresent(qm -> {
|
||||
monitorChannel = null;
|
||||
|
|
@ -259,7 +261,8 @@ public class QemuMonitor extends Component {
|
|||
* @param event the event
|
||||
*/
|
||||
@Handler
|
||||
@SuppressWarnings("PMD.AvoidLiteralsInIfCondition")
|
||||
@SuppressWarnings({ "PMD.AvoidLiteralsInIfCondition",
|
||||
"PMD.AvoidSynchronizedStatement" })
|
||||
public void onExecQmpCommand(MonitorCommand event) {
|
||||
var command = event.command();
|
||||
logger.fine(() -> "monitor(out): " + command.toString());
|
||||
|
|
@ -290,6 +293,7 @@ public class QemuMonitor extends Component {
|
|||
* @param event the event
|
||||
*/
|
||||
@Handler(priority = 100)
|
||||
@SuppressWarnings("PMD.AvoidSynchronizedStatement")
|
||||
public void onStop(Stop event) {
|
||||
if (monitorChannel != null) {
|
||||
// We have a connection to Qemu, attempt ACPI shutdown.
|
||||
|
|
@ -321,6 +325,7 @@ public class QemuMonitor extends Component {
|
|||
* @param event the event
|
||||
*/
|
||||
@Handler
|
||||
@SuppressWarnings("PMD.AvoidSynchronizedStatement")
|
||||
public void onPowerdownEvent(PowerdownEvent event) {
|
||||
synchronized (this) {
|
||||
// Cancel confirmation timeout
|
||||
|
|
@ -349,6 +354,7 @@ public class QemuMonitor extends Component {
|
|||
* @param event the event
|
||||
*/
|
||||
@Handler
|
||||
@SuppressWarnings("PMD.AvoidSynchronizedStatement")
|
||||
public void onConfigureQemu(ConfigureQemu event) {
|
||||
int newTimeout = event.configuration().vm.powerdownTimeout;
|
||||
if (powerdownTimeout != newTimeout) {
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ import java.nio.file.Path;
|
|||
import java.nio.file.Paths;
|
||||
import java.time.Instant;
|
||||
import java.util.Comparator;
|
||||
import java.util.EnumSet;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
|
|
@ -227,7 +227,7 @@ public class Runner extends Component {
|
|||
CloudInit
|
||||
}
|
||||
|
||||
private final Set<QemuPreps> qemuLatch = new HashSet<>();
|
||||
private final Set<QemuPreps> qemuLatch = EnumSet.noneOf(QemuPreps.class);
|
||||
|
||||
/**
|
||||
* Instantiates a new runner.
|
||||
|
|
@ -483,6 +483,7 @@ public class Runner extends Component {
|
|||
mayBeStartQemu(QemuPreps.Config);
|
||||
}
|
||||
|
||||
@SuppressWarnings("PMD.AvoidSynchronizedStatement")
|
||||
private void mayBeStartQemu(QemuPreps done) {
|
||||
synchronized (qemuLatch) {
|
||||
if (qemuLatch.isEmpty()) {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ plugins {
|
|||
dependencies {
|
||||
implementation project(':org.jdrupes.vmoperator.manager.events')
|
||||
|
||||
implementation 'org.jgrapes:org.jgrapes.webconsole.base:[1.8.0,2)'
|
||||
implementation 'org.jgrapes:org.jgrapes.webconsole.base:[2.0.0.3)'
|
||||
implementation 'org.jgrapes:org.jgrapes.webconsole.provider.vue:[1,2)'
|
||||
implementation 'org.jgrapes:org.jgrapes.webconsole.provider.jgwcvuecomponents:[1.2,2)'
|
||||
implementation 'org.jgrapes:org.jgrapes.webconsole.provider.chartjs:[1.2,2)'
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
package org.jdrupes.vmoperator.vmconlet;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonObject;
|
||||
import freemarker.core.ParseException;
|
||||
import freemarker.template.MalformedTemplateNameException;
|
||||
|
|
@ -33,8 +34,6 @@ import java.time.Instant;
|
|||
import java.util.EnumSet;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import org.jdrupes.json.JsonBeanDecoder;
|
||||
import org.jdrupes.json.JsonDecodeException;
|
||||
import org.jdrupes.vmoperator.common.K8sObserver;
|
||||
import org.jdrupes.vmoperator.common.VmDefinitionModel;
|
||||
import org.jdrupes.vmoperator.manager.events.ChannelTracker;
|
||||
|
|
@ -160,10 +159,9 @@ public class VmConlet extends FreeMarkerConlet<VmConlet.VmsModel> {
|
|||
sendVmInfos = true;
|
||||
}
|
||||
if (sendVmInfos) {
|
||||
for (var vmDef : channelTracker.associated()) {
|
||||
var def
|
||||
= JsonBeanDecoder.create(vmDef.data().toString())
|
||||
.readObject();
|
||||
for (var item : channelTracker.values()) {
|
||||
Gson gson = item.channel().client().getJSON().getGson();
|
||||
var def = gson.fromJson(item.associated().data(), Object.class);
|
||||
channel.respond(new NotifyConletView(type(),
|
||||
conletId, "updateVm", def));
|
||||
}
|
||||
|
|
@ -185,7 +183,7 @@ public class VmConlet extends FreeMarkerConlet<VmConlet.VmsModel> {
|
|||
"PMD.AvoidInstantiatingObjectsInLoops", "PMD.AvoidDuplicateLiterals",
|
||||
"PMD.ConfusingArgumentToVarargsMethod" })
|
||||
public void onVmDefChanged(VmDefChanged event, VmChannel channel)
|
||||
throws JsonDecodeException, IOException {
|
||||
throws IOException {
|
||||
var vmName = event.vmDefinition().getMetadata().getName();
|
||||
if (event.type() == K8sObserver.ResponseType.DELETED) {
|
||||
channelTracker.remove(vmName);
|
||||
|
|
@ -196,11 +194,11 @@ public class VmConlet extends FreeMarkerConlet<VmConlet.VmsModel> {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
var vmDef = new VmDefinitionModel(channel.client().getJSON()
|
||||
.getGson(), cleanup(event.vmDefinition().data()));
|
||||
var gson = channel.client().getJSON().getGson();
|
||||
var vmDef = new VmDefinitionModel(gson,
|
||||
cleanup(event.vmDefinition().data()));
|
||||
channelTracker.put(vmName, channel, vmDef);
|
||||
var def = JsonBeanDecoder.create(vmDef.data().toString())
|
||||
.readObject();
|
||||
var def = gson.fromJson(vmDef.data(), Object.class);
|
||||
for (var entry : conletIdsByConsoleConnection().entrySet()) {
|
||||
for (String conletId : entry.getValue()) {
|
||||
entry.getKey().respond(new NotifyConletView(type(),
|
||||
|
|
@ -346,7 +344,7 @@ public class VmConlet extends FreeMarkerConlet<VmConlet.VmsModel> {
|
|||
ConsoleConnection channel, VmsModel conletState)
|
||||
throws Exception {
|
||||
event.stop();
|
||||
var vmName = event.params().asString(0);
|
||||
String vmName = event.param(0);
|
||||
var vmChannel = channelTracker.channel(vmName).orElse(null);
|
||||
if (vmChannel == null) {
|
||||
return;
|
||||
|
|
@ -360,12 +358,12 @@ public class VmConlet extends FreeMarkerConlet<VmConlet.VmsModel> {
|
|||
break;
|
||||
case "cpus":
|
||||
fire(new ModifyVm(vmName, "currentCpus",
|
||||
new BigDecimal(event.params().asDouble(1)).toBigInteger(),
|
||||
new BigDecimal(event.param(1).toString()).toBigInteger(),
|
||||
vmChannel));
|
||||
break;
|
||||
case "ram":
|
||||
fire(new ModifyVm(vmName, "currentRam",
|
||||
new Quantity(new BigDecimal(event.params().asDouble(1)),
|
||||
new Quantity(new BigDecimal(event.param(1).toString()),
|
||||
Format.BINARY_SI).toSuffixedString(),
|
||||
vmChannel));
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ plugins {
|
|||
dependencies {
|
||||
implementation project(':org.jdrupes.vmoperator.manager.events')
|
||||
|
||||
implementation 'org.jgrapes:org.jgrapes.webconsole.base:[1.8.0,2)'
|
||||
implementation 'org.jgrapes:org.jgrapes.webconsole.base:[2.0.0,3)'
|
||||
implementation 'org.jgrapes:org.jgrapes.webconsole.provider.vue:[1,2)'
|
||||
implementation 'org.jgrapes:org.jgrapes.webconsole.provider.jgwcvuecomponents:[1.2,2)'
|
||||
implementation 'org.jgrapes:org.jgrapes.webconsole.provider.chartjs:[1.2,2)'
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import com.google.gson.JsonSyntaxException;
|
||||
import freemarker.core.ParseException;
|
||||
import freemarker.template.MalformedTemplateNameException;
|
||||
import freemarker.template.Template;
|
||||
|
|
@ -47,8 +48,6 @@ import java.util.ResourceBundle;
|
|||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import org.bouncycastle.util.Objects;
|
||||
import org.jdrupes.json.JsonBeanDecoder;
|
||||
import org.jdrupes.json.JsonDecodeException;
|
||||
import org.jdrupes.vmoperator.common.K8sDynamicModel;
|
||||
import org.jdrupes.vmoperator.common.K8sObserver;
|
||||
import org.jdrupes.vmoperator.common.VmDefinitionModel;
|
||||
|
|
@ -153,7 +152,7 @@ public class VmViewer extends FreeMarkerConlet<VmViewer.ViewerModel> {
|
|||
*
|
||||
* @param event the event
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
@SuppressWarnings({ "unchecked", "PMD.AvoidDuplicateLiterals" })
|
||||
@Handler
|
||||
public void onConfigurationUpdate(ConfigurationUpdate event) {
|
||||
event.structured(componentPath()).ifPresent(c -> {
|
||||
|
|
@ -419,16 +418,19 @@ public class VmViewer extends FreeMarkerConlet<VmViewer.ViewerModel> {
|
|||
if (Strings.isNullOrEmpty(model.vmName())) {
|
||||
return;
|
||||
}
|
||||
channelTracker.associated(model.vmName()).ifPresent(vmDef -> {
|
||||
channelTracker.value(model.vmName()).ifPresent(item -> {
|
||||
try {
|
||||
var def = JsonBeanDecoder.create(vmDef.data().toString())
|
||||
.readObject();
|
||||
def.setField("userPermissions",
|
||||
var vmDef = item.associated();
|
||||
@SuppressWarnings("unchecked")
|
||||
var def = (Map<String, Object>) item.channel().client()
|
||||
.getJSON().getGson()
|
||||
.fromJson(vmDef.data().toString(), Map.class);
|
||||
def.put("userPermissions",
|
||||
permissions(vmDef, channel.session()).stream()
|
||||
.map(Permission::toString).toList());
|
||||
channel.respond(new NotifyConletView(type(),
|
||||
model.getConletId(), "updateVmDefinition", def));
|
||||
} catch (JsonDecodeException e) {
|
||||
} catch (JsonSyntaxException e) {
|
||||
logger.log(Level.SEVERE, e,
|
||||
() -> "Failed to serialize VM definition");
|
||||
}
|
||||
|
|
@ -458,7 +460,7 @@ public class VmViewer extends FreeMarkerConlet<VmViewer.ViewerModel> {
|
|||
"PMD.AvoidInstantiatingObjectsInLoops", "PMD.AvoidDuplicateLiterals",
|
||||
"PMD.ConfusingArgumentToVarargsMethod" })
|
||||
public void onVmDefChanged(VmDefChanged event, VmChannel channel)
|
||||
throws JsonDecodeException, IOException {
|
||||
throws IOException {
|
||||
var vmDef = new VmDefinitionModel(channel.client().getJSON()
|
||||
.getGson(), event.vmDefinition().data());
|
||||
GsonPtr.to(vmDef.data()).to("metadata").get(JsonObject.class)
|
||||
|
|
@ -547,7 +549,7 @@ public class VmViewer extends FreeMarkerConlet<VmViewer.ViewerModel> {
|
|||
|
||||
private void selectVm(NotifyConletModel event, ConsoleConnection channel,
|
||||
ViewerModel model) throws JsonProcessingException {
|
||||
model.setVmName(event.params().asString(0));
|
||||
model.setVmName(event.param(0));
|
||||
String jsonState = objectMapper.writeValueAsString(model);
|
||||
channel.respond(new KeyValueStoreUpdate().update(storagePath(
|
||||
channel.session(), model.getConletId()), jsonState));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue