Prepare release.
This commit is contained in:
parent
659463b3b4
commit
65a5cfd286
39 changed files with 500 additions and 132 deletions
|
|
@ -18,10 +18,10 @@ dependencies {
|
|||
implementation 'org.jgrapes:org.jgrapes.http:[3.1.0,4)'
|
||||
implementation 'org.jgrapes:org.jgrapes.util:[1.34.0,2)'
|
||||
|
||||
implementation 'org.jgrapes:org.jgrapes.webconsole.base:[1.5.0,2)'
|
||||
implementation 'org.jgrapes:org.jgrapes.webconsole.base:[1.7.0,2)'
|
||||
implementation 'org.jgrapes:org.jgrapes.webconsole.vuejs:[1.5.0,2)'
|
||||
implementation 'org.jgrapes:org.jgrapes.webconsole.rbac:[1.3.0,2)'
|
||||
implementation 'org.jgrapes:org.jgrapes.webconlet.oidclogin:[1.3.0,2)'
|
||||
implementation 'org.jgrapes:org.jgrapes.webconlet.oidclogin:[1.4.0,2)'
|
||||
implementation 'org.jgrapes:org.jgrapes.webconlet.markdowndisplay:[1.2.0,2)'
|
||||
|
||||
runtimeOnly 'org.jgrapes:org.jgrapes.webconlet.sysinfo:[1.4.0,2)'
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
You can use the "puzzle piece" icon on the top right corner of the
|
||||
You can use the "puzzle piece" icon on the top right corner of the
|
||||
page to add display widgets (conlets) to the overview tab.
|
||||
|
||||
Use the "full screen" icon on the top right corner of any
|
||||
conlet (if available) to get a detailed view.
|
||||
conlet (if available) to get a detailed view.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
Verwenden Sie das "Puzzle"-Icon auf der rechten oberen Ecke
|
||||
Verwenden Sie das "Puzzle"-Icon auf der rechten oberen Ecke
|
||||
der Seite, um Anzeige-Widgets (Conlets) hinzuzufügen.
|
||||
|
||||
Wenn sich in der rechten oberen Ecke eines Conlets ein Vollbild-Icon
|
||||
|
|
|
|||
|
|
@ -48,6 +48,12 @@ data:
|
|||
# Whether a shutdown initiated by the guest stops the pod deployment
|
||||
guestShutdownStops: ${ cr.spec.guestShutdownStops!false?c }
|
||||
|
||||
# When incremented, the VM is reset. The value has no default value,
|
||||
# i.e. if you start the VM without a value for this property, and
|
||||
# decide to trigger a reset later, you have to first set the value
|
||||
# and then inrement it.
|
||||
resetCounter: ${ cr.resetCount }
|
||||
|
||||
# Forward the cloud-init data if provided
|
||||
<#if cr.spec.cloudInit??>
|
||||
cloudInit:
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ import org.jdrupes.vmoperator.common.K8s;
|
|||
import static org.jdrupes.vmoperator.manager.Constants.APP_NAME;
|
||||
import static org.jdrupes.vmoperator.manager.Constants.VM_OP_NAME;
|
||||
import org.jdrupes.vmoperator.manager.events.VmChannel;
|
||||
import org.jdrupes.vmoperator.manager.events.VmDefChanged;
|
||||
import org.yaml.snakeyaml.LoaderOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
import org.yaml.snakeyaml.constructor.SafeConstructor;
|
||||
|
|
@ -62,7 +61,6 @@ import org.yaml.snakeyaml.constructor.SafeConstructor;
|
|||
/**
|
||||
* Reconcile.
|
||||
*
|
||||
* @param event the event
|
||||
* @param model the model
|
||||
* @param channel the channel
|
||||
* @return the dynamic kubernetes object
|
||||
|
|
@ -70,8 +68,8 @@ import org.yaml.snakeyaml.constructor.SafeConstructor;
|
|||
* @throws TemplateException the template exception
|
||||
* @throws ApiException the api exception
|
||||
*/
|
||||
public DynamicKubernetesObject reconcile(VmDefChanged event,
|
||||
Map<String, Object> model, VmChannel channel)
|
||||
public DynamicKubernetesObject reconcile(Map<String, Object> model,
|
||||
VmChannel channel)
|
||||
throws IOException, TemplateException, ApiException {
|
||||
// Get API
|
||||
DynamicKubernetesApi cmApi = new DynamicKubernetesApi("", "v1",
|
||||
|
|
|
|||
|
|
@ -181,13 +181,12 @@ public class Controller extends Component {
|
|||
@Handler
|
||||
public void onModifyVm(ModifyVm event, VmChannel channel)
|
||||
throws ApiException, IOException {
|
||||
patchVmSpec(channel.client(), event.name(), event.path(),
|
||||
patchVmDef(channel.client(), event.name(), "spec/vm/" + event.path(),
|
||||
event.value());
|
||||
}
|
||||
|
||||
private void patchVmSpec(K8sClient client, String name, String path,
|
||||
Object value)
|
||||
throws ApiException, IOException {
|
||||
private void patchVmDef(K8sClient client, String name, String path,
|
||||
Object value) throws ApiException, IOException {
|
||||
var vmStub = K8sDynamicStub.get(client,
|
||||
new GroupVersionKind(VM_OP_GROUP, "", VM_OP_KIND_VM), namespace,
|
||||
name);
|
||||
|
|
@ -197,7 +196,7 @@ public class Controller extends Component {
|
|||
? "\"" + value + "\""
|
||||
: value.toString();
|
||||
var res = vmStub.patch(V1Patch.PATCH_FORMAT_JSON_PATCH,
|
||||
new V1Patch("[{\"op\": \"replace\", \"path\": \"/spec/vm/"
|
||||
new V1Patch("[{\"op\": \"replace\", \"path\": \"/"
|
||||
+ path + "\", \"value\": " + valueAsText + "}]"),
|
||||
client.defaultPatchOptions());
|
||||
if (!res.isPresent()) {
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ import java.util.Collections;
|
|||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Scanner;
|
||||
import java.util.logging.Level;
|
||||
import static org.jdrupes.vmoperator.common.Constants.APP_NAME;
|
||||
|
|
@ -180,7 +181,8 @@ public class DisplaySecretMonitor
|
|||
// Check validity
|
||||
var model = stub.model().get();
|
||||
@SuppressWarnings("PMD.StringInstantiation")
|
||||
var expiry = new String(model.getData().get(DATA_PASSWORD_EXPIRY));
|
||||
var expiry = Optional.ofNullable(model.getData()
|
||||
.get(DATA_PASSWORD_EXPIRY)).map(b -> new String(b)).orElse(null);
|
||||
if (model.getData().get(DATA_DISPLAY_PASSWORD) != null
|
||||
&& stillValid(expiry)) {
|
||||
event.setResult(
|
||||
|
|
|
|||
|
|
@ -64,7 +64,7 @@ import org.jose4j.base64url.Base64;
|
|||
var display = GsonPtr.to(event.vmDefinition().data()).to("spec", "vm",
|
||||
"display");
|
||||
if (!display.get(JsonPrimitive.class, "spice", "generateSecret")
|
||||
.map(JsonPrimitive::getAsBoolean).orElse(false)) {
|
||||
.map(JsonPrimitive::getAsBoolean).orElse(true)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ import org.jdrupes.vmoperator.common.K8sDynamicModel;
|
|||
import org.jdrupes.vmoperator.common.K8sObserver;
|
||||
import org.jdrupes.vmoperator.common.K8sV1SecretStub;
|
||||
import static org.jdrupes.vmoperator.manager.Constants.COMP_DISPLAY_SECRET;
|
||||
import org.jdrupes.vmoperator.manager.events.ResetVm;
|
||||
import org.jdrupes.vmoperator.manager.events.VmChannel;
|
||||
import org.jdrupes.vmoperator.manager.events.VmDefChanged;
|
||||
import org.jdrupes.vmoperator.util.ExtendedObjectWrapper;
|
||||
|
|
@ -209,13 +210,35 @@ public class Reconciler extends Component {
|
|||
// Reconcile, use "augmented" vm definition for model
|
||||
Map<String, Object> model
|
||||
= prepareModel(channel.client(), patchCr(event.vmDefinition()));
|
||||
var configMap = cmReconciler.reconcile(event, model, channel);
|
||||
var configMap = cmReconciler.reconcile(model, channel);
|
||||
model.put("cm", configMap.getRaw());
|
||||
dsReconciler.reconcile(event, model, channel);
|
||||
stsReconciler.reconcile(event, model, channel);
|
||||
lbReconciler.reconcile(event, model, channel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset the VM by incrementing the reset count and doing a
|
||||
* partial reconcile (configmap only).
|
||||
*
|
||||
* @param event the event
|
||||
* @param channel the channel
|
||||
* @throws IOException
|
||||
* @throws ApiException
|
||||
* @throws TemplateException
|
||||
*/
|
||||
@Handler
|
||||
public void onResetVm(ResetVm event, VmChannel channel)
|
||||
throws ApiException, IOException, TemplateException {
|
||||
var defRoot
|
||||
= GsonPtr.to(channel.vmDefinition().data()).get(JsonObject.class);
|
||||
defRoot.addProperty("resetCount",
|
||||
defRoot.get("resetCount").getAsLong() + 1);
|
||||
Map<String, Object> model
|
||||
= prepareModel(channel.client(), patchCr(channel.vmDefinition()));
|
||||
cmReconciler.reconcile(model, channel);
|
||||
}
|
||||
|
||||
private DynamicKubernetesObject patchCr(K8sDynamicModel vmDef) {
|
||||
var json = vmDef.data().deepCopy();
|
||||
// Adjust cdromImage path
|
||||
|
|
|
|||
|
|
@ -25,13 +25,13 @@ import io.kubernetes.client.openapi.models.V1ObjectMeta;
|
|||
import io.kubernetes.client.util.Watch;
|
||||
import io.kubernetes.client.util.generic.options.ListOptions;
|
||||
import java.io.IOException;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.stream.Collectors;
|
||||
import static org.jdrupes.vmoperator.common.Constants.VM_OP_GROUP;
|
||||
import org.jdrupes.vmoperator.common.K8s;
|
||||
import org.jdrupes.vmoperator.common.K8sClient;
|
||||
import org.jdrupes.vmoperator.common.K8sDynamicModel;
|
||||
import org.jdrupes.vmoperator.common.K8sDynamicStub;
|
||||
import org.jdrupes.vmoperator.common.K8sObserver.ResponseType;
|
||||
import org.jdrupes.vmoperator.common.K8sV1ConfigMapStub;
|
||||
|
|
@ -121,7 +121,7 @@ public class VmMonitor extends
|
|||
}
|
||||
if (vmDef.data() != null) {
|
||||
// New data, augment and save
|
||||
addDynamicData(channel.client(), vmDef);
|
||||
addDynamicData(channel.client(), vmDef, channel.vmDefinition());
|
||||
channel.setVmDefinition(vmDef);
|
||||
} else {
|
||||
// Reuse cached
|
||||
|
|
@ -151,8 +151,16 @@ public class VmMonitor extends
|
|||
}
|
||||
}
|
||||
|
||||
private void addDynamicData(K8sClient client, K8sDynamicModel vmState) {
|
||||
private void addDynamicData(K8sClient client, VmDefinitionModel vmState,
|
||||
VmDefinitionModel prevState) {
|
||||
var rootNode = GsonPtr.to(vmState.data()).get(JsonObject.class);
|
||||
|
||||
// Maintain (or initialize) the resetCount
|
||||
rootNode.addProperty("resetCount", Optional.ofNullable(prevState)
|
||||
.map(ps -> GsonPtr.to(ps.data()))
|
||||
.flatMap(d -> d.getAsLong("resetCount")).orElse(0L));
|
||||
|
||||
// Add defaults in case the VM is not running
|
||||
rootNode.addProperty("nodeName", "");
|
||||
rootNode.addProperty("nodeAddress", "");
|
||||
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@
|
|||
* ```
|
||||
*
|
||||
* Developers may also be interested in the usage of channels
|
||||
* by the application's component:
|
||||
* by the application's components:
|
||||
*
|
||||
* 
|
||||
*
|
||||
|
|
@ -74,6 +74,8 @@
|
|||
*
|
||||
* Component NioDispatcher as NioDispatcher <<internal>>
|
||||
* [Manager] *-up- [NioDispatcher]
|
||||
* Component HttpConnector as HttpConnector <<internal>>
|
||||
* [Manager] *-up- [HttpConnector]
|
||||
* Component FileSystemWatcher as FileSystemWatcher <<internal>>
|
||||
* [Manager] *-up- [FileSystemWatcher]
|
||||
* Component YamlConfigurationStore as YamlConfigurationStore <<internal>>
|
||||
|
|
@ -119,6 +121,7 @@
|
|||
* [WebConsole] *-- [RoleConfigurator]
|
||||
* [WebConsole] *-- [RoleConletFilter]
|
||||
* [WebConsole] *-left- [LoginConlet]
|
||||
* [WebConsole] *-right- [OidcClient]
|
||||
*
|
||||
* Component "ComponentCollector\nfor page resources" as cpr <<internal>>
|
||||
* [WebConsole] *-- [cpr]
|
||||
|
|
@ -147,21 +150,35 @@
|
|||
* () "guiTransport" as hT
|
||||
* hT .up. [GuiSocketServer:8080]
|
||||
* hT .down. [GuiHttpServer]
|
||||
* hT .right[hidden]. [HttpConnector]
|
||||
*
|
||||
* [YamlConfigurationStore] -right[hidden]- hT
|
||||
*
|
||||
* () "guiHttp" as http
|
||||
* http .up. [GuiHttpServer]
|
||||
* http .up. [HttpConnector]
|
||||
* note top of [HttpConnector]: transport layer com-\nponents omitted
|
||||
*
|
||||
* [PreferencesStore] .right. http
|
||||
* [PreferencesStore] .. http
|
||||
* [OidcClient] .up. http
|
||||
* [LanguageSelector] .left. http
|
||||
* [InMemorySessionManager] .up. http
|
||||
* [LanguageSelector] .up. http
|
||||
*
|
||||
* package "Conceptual WebConsole" {
|
||||
* [ConsoleWeblet] .left. http
|
||||
* [ConsoleWeblet] .right. http
|
||||
* [ConsoleWeblet] *-down- [WebConsole]
|
||||
* }
|
||||
*
|
||||
* [Controller] .down[hidden]. [ConsoleWeblet]
|
||||
*
|
||||
* () "console" as console
|
||||
* console .. WebConsole
|
||||
*
|
||||
* [OidcClient] .. console
|
||||
* [LoginConlet] .right. console
|
||||
*
|
||||
* note right of console: More conlets\nconnect here
|
||||
*
|
||||
* @enduml
|
||||
*/
|
||||
package org.jdrupes.vmoperator.manager;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue