diff --git a/README.md b/README.md index 52a2fa8..9118f9d 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,8 @@ # Run Qemu in Kubernetes Pods -The goal of this project is to provide the means for running Qemu -based VMs in Kubernetes pods. +The goal of this project is to provide easy to use and flexible components +for running Qemu based VMs in Kubernetes pods. See the [project's home page](https://jdrupes.org/vm-operator/) for details. diff --git a/build.gradle b/build.gradle index d0ebc71..df173d8 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,8 @@ buildscript { plugins { id 'org.ajoberstar.grgit' version '5.2.0' apply false id 'org.ajoberstar.git-publish' version '4.2.0' apply false - id 'pl.allegro.tech.build.axion-release' version '1.15.0' apply false + id 'pl.allegro.tech.build.axion-release' version '1.17.2' apply false + id 'org.jdrupes.vmoperator.versioning-conventions' id 'org.jdrupes.vmoperator.java-doc-conventions' id 'eclipse' id "com.github.node-gradle.node" version "7.0.1" diff --git a/deploy/crds/vms-crd.yaml b/deploy/crds/vms-crd.yaml index bfe3985..cda817c 100644 --- a/deploy/crds/vms-crd.yaml +++ b/deploy/crds/vms-crd.yaml @@ -1410,6 +1410,9 @@ spec: display: type: object properties: + outputs: + type: integer + default: 1 spice: type: object properties: diff --git a/org.jdrupes.vmoperator.common/src/org/jdrupes/vmoperator/common/K8sObserver.java b/org.jdrupes.vmoperator.common/src/org/jdrupes/vmoperator/common/K8sObserver.java index 2545a30..600b5ca 100644 --- a/org.jdrupes.vmoperator.common/src/org/jdrupes/vmoperator/common/K8sObserver.java +++ b/org.jdrupes.vmoperator.common/src/org/jdrupes/vmoperator/common/K8sObserver.java @@ -85,7 +85,7 @@ public class K8sObserver(objectClass, objectListClass, context.getGroup(), context.getPreferredVersion(), context.getResourcePlural(), client); - thread = new Thread(() -> { + thread = Thread.ofVirtual().unstarted(() -> { try { logger.config(() -> "Watching " + context.getResourcePlural() + " (" + context.getPreferredVersion() + ")" @@ -100,7 +100,7 @@ public class K8sObserver "Problem watching" + " (will retry): " + e.getMessage()); delayRestart(startedAt); @@ -117,7 +117,6 @@ public class K8sObserver display: + <#if cr.spec.vm.display.outputs?? > + outputs: ${ cr.spec.vm.display.outputs.asInt?c } + <#if cr.spec.vm.display.spice??> spice: port: ${ cr.spec.vm.display.spice.port.asInt?c } diff --git a/org.jdrupes.vmoperator.runner.qemu/build.gradle b/org.jdrupes.vmoperator.runner.qemu/build.gradle index 8cea1ae..7a0e2bd 100644 --- a/org.jdrupes.vmoperator.runner.qemu/build.gradle +++ b/org.jdrupes.vmoperator.runner.qemu/build.gradle @@ -9,10 +9,10 @@ plugins { } dependencies { - implementation 'org.jgrapes:org.jgrapes.core:[1.19.0,2)' - implementation 'org.jgrapes:org.jgrapes.io:[2.7.0,3)' - implementation 'org.jgrapes:org.jgrapes.http:[3.1.0,4)' - implementation 'org.jgrapes:org.jgrapes.util:[1.31.0,2)' + implementation 'org.jgrapes:org.jgrapes.core:[1.21.0,2)' + implementation 'org.jgrapes:org.jgrapes.util:[1.36.0,2)' + implementation 'org.jgrapes:org.jgrapes.io:[2.11.0,3)' + implementation 'org.jgrapes:org.jgrapes.http:[3.5.0,4)' implementation project(':org.jdrupes.vmoperator.common') implementation 'commons-cli:commons-cli:1.5.0' @@ -33,6 +33,7 @@ application { project.ext.gitBranch = grgit.branch.current.name.replace('/', '-') def registry = "${project.rootProject.properties['docker.registry']}" +def rootVersion = rootProject.version task buildImageArch(type: Exec) { dependsOn installDist @@ -54,7 +55,7 @@ task pushImageArch(type: Exec) { task tagWithVersionArch(type: Exec) { dependsOn pushImageArch - enabled = !project.version.contains("SNAPSHOT") + enabled = !rootVersion.contains("SNAPSHOT") commandLine 'podman', 'push', \ "${project.name}-arch:${project.gitBranch}",\ @@ -64,9 +65,9 @@ task tagWithVersionArch(type: Exec) { task tagAsLatestArch(type: Exec) { dependsOn tagWithVersionArch - enabled = !project.version.contains("SNAPSHOT") - && !project.version.contains("alpha") \ - && !project.version.contains("beta") \ + enabled = !rootVersion.contains("SNAPSHOT") + && !rootVersion.contains("alpha") \ + && !rootVersion.contains("beta") \ || project.rootProject.properties['docker.testRegistry'] \ && project.rootProject.properties['docker.registry'] \ == project.rootProject.properties['docker.testRegistry'] @@ -96,7 +97,7 @@ task pushImageAlpine(type: Exec) { task tagWithVersionAlpine(type: Exec) { dependsOn pushImageAlpine - enabled = !project.version.contains("SNAPSHOT") + enabled = !rootVersion.contains("SNAPSHOT") commandLine 'podman', 'push', \ "${project.name}-alpine:${project.gitBranch}",\ @@ -106,9 +107,9 @@ task tagWithVersionAlpine(type: Exec) { task tagAsLatestAlpine(type: Exec) { dependsOn tagWithVersionAlpine - enabled = !project.version.contains("SNAPSHOT") - && !project.version.contains("alpha") \ - && !project.version.contains("beta") \ + enabled = !rootVersion.contains("SNAPSHOT") + && !rootVersion.contains("alpha") \ + && !rootVersion.contains("beta") \ || project.rootProject.properties['docker.testRegistry'] \ && project.rootProject.properties['docker.registry'] \ == project.rootProject.properties['docker.testRegistry'] diff --git a/org.jdrupes.vmoperator.runner.qemu/password-expiry b/org.jdrupes.vmoperator.runner.qemu/password-expiry index c42fe6e..8a606d5 100644 --- a/org.jdrupes.vmoperator.runner.qemu/password-expiry +++ b/org.jdrupes.vmoperator.runner.qemu/password-expiry @@ -1 +1 @@ -+30 \ No newline at end of file ++1800 \ No newline at end of file diff --git a/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/Configuration.java b/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/Configuration.java index 4e89944..dd45147 100644 --- a/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/Configuration.java +++ b/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/Configuration.java @@ -245,6 +245,9 @@ public class Configuration implements Dto { */ public static class Display implements Dto { + /** The number of outputs. */ + public int outputs = 1; + /** The spice. */ public Spice spice; } diff --git a/org.jdrupes.vmoperator.runner.qemu/templates/Standard-VM-latest.ftl.yaml b/org.jdrupes.vmoperator.runner.qemu/templates/Standard-VM-latest.ftl.yaml index d100554..5d10b54 100644 --- a/org.jdrupes.vmoperator.runner.qemu/templates/Standard-VM-latest.ftl.yaml +++ b/org.jdrupes.vmoperator.runner.qemu/templates/Standard-VM-latest.ftl.yaml @@ -137,7 +137,8 @@ - [ "-device", "virtio-rng-pci,rng=objrng0,id=rng0" ] # * Graphics and Audio Card # This is the only video "card" without a flickering cursor. - - [ "-device", "virtio-vga,id=video0,max_outputs=1" ] + - [ "-device", "virtio-vga,id=video0,max_outputs=${ vm.display.outputs },\ + max_hostmem=${ (vm.display.outputs * 256 * 1024 * 1024)?c }" ] - [ "-device", "ich9-intel-hda,id=sound0" ] # Network <#assign nwCounter = 0/> diff --git a/org.jdrupes.vmoperator.vmconlet/build.gradle b/org.jdrupes.vmoperator.vmconlet/build.gradle index ab667f5..3f1f18e 100644 --- a/org.jdrupes.vmoperator.vmconlet/build.gradle +++ b/org.jdrupes.vmoperator.vmconlet/build.gradle @@ -5,7 +5,7 @@ plugins { dependencies { implementation project(':org.jdrupes.vmoperator.manager.events') - implementation 'org.jgrapes:org.jgrapes.webconsole.base:[1.3.0,2)' + implementation 'org.jgrapes:org.jgrapes.webconsole.base:[1.8.0,2)' 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)' diff --git a/org.jdrupes.vmoperator.vmviewer/build.gradle b/org.jdrupes.vmoperator.vmviewer/build.gradle index aca015b..3f1f18e 100644 --- a/org.jdrupes.vmoperator.vmviewer/build.gradle +++ b/org.jdrupes.vmoperator.vmviewer/build.gradle @@ -5,7 +5,7 @@ plugins { dependencies { implementation project(':org.jdrupes.vmoperator.manager.events') - implementation 'org.jgrapes:org.jgrapes.webconsole.base:[1.7.0,2)' + implementation 'org.jgrapes:org.jgrapes.webconsole.base:[1.8.0,2)' 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)' diff --git a/org.jdrupes.vmoperator.vmviewer/src/org/jdrupes/vmoperator/vmviewer/browser/VmViewer-style.scss b/org.jdrupes.vmoperator.vmviewer/src/org/jdrupes/vmoperator/vmviewer/browser/VmViewer-style.scss index 6d0654f..3ee432a 100644 --- a/org.jdrupes.vmoperator.vmviewer/src/org/jdrupes/vmoperator/vmviewer/browser/VmViewer-style.scss +++ b/org.jdrupes.vmoperator.vmviewer/src/org/jdrupes/vmoperator/vmviewer/browser/VmViewer-style.scss @@ -72,6 +72,7 @@ position: absolute; animation: spin 2s linear infinite; z-index: 100; + pointer-events: none; } } diff --git a/overview.md b/overview.md index 0677d51..447a33c 100644 --- a/overview.md +++ b/overview.md @@ -3,5 +3,8 @@ A Kubernetes operator for running VMs as pods. VM-Operator =========== -The VM-operator is built on the [JGrapes](https://mnlipp.github.io/jgrapes/) -event driven framework. +The VM-operator enables you to easily run Qemu based VMs as pods +in Kubernetes. It is built on the +[JGrapes](https://mnlipp.github.io/jgrapes/) event driven framework. + +See the project's [home page](https://jdrupes.org/vm-operator/) for details. diff --git a/spice-squid/build.gradle b/spice-squid/build.gradle index e7ccd00..5278098 100644 --- a/spice-squid/build.gradle +++ b/spice-squid/build.gradle @@ -7,6 +7,7 @@ dependencies { project.ext.gitBranch = grgit.branch.current.name.replace('/', '-') def registry = "${project.rootProject.properties['docker.registry']}" +def rootVersion = rootProject.version task buildImage(type: Exec) { inputs.files 'Containerfile' @@ -26,7 +27,7 @@ task pushImage(type: Exec) { task tagWithVersion(type: Exec) { dependsOn pushImage - enabled = !project.version.contains("SNAPSHOT") + enabled = !rootVersion.contains("SNAPSHOT") commandLine 'podman', 'push', \ "${project.name}:${project.gitBranch}",\ @@ -36,9 +37,9 @@ task tagWithVersion(type: Exec) { task tagAsLatest(type: Exec) { dependsOn tagWithVersion - enabled = !project.version.contains("SNAPSHOT") - && !project.version.contains("alpha") \ - && !project.version.contains("beta") \ + enabled = !rootVersion.contains("SNAPSHOT") + && !rootVersion.contains("alpha") \ + && !rootVersion.contains("beta") \ || project.rootProject.properties['docker.testRegistry'] \ && project.rootProject.properties['docker.registry'] \ == project.rootProject.properties['docker.testRegistry'] diff --git a/webpages/_layouts/vm-operator.html b/webpages/_layouts/vm-operator.html index dfe4220..30e6407 100644 --- a/webpages/_layouts/vm-operator.html +++ b/webpages/_layouts/vm-operator.html @@ -18,8 +18,8 @@
@@ -40,11 +40,11 @@ -

The Web-GUI

+

Web interface

Upgrading

Javadoc

diff --git a/webpages/stylesheets/styles.css b/webpages/stylesheets/styles.css index 748ffcb..8d6b803 100644 --- a/webpages/stylesheets/styles.css +++ b/webpages/stylesheets/styles.css @@ -5,7 +5,7 @@ body { color:#595959; } -h1, h2, h3, h4, h5, h6 { +h1, h2, h3, h4, h5, h6, .index-title, .index-subtitle { color:#222; margin:0 0 20px; } @@ -14,11 +14,11 @@ p, ul, ol, table, pre, dl { margin:0 0 20px; } -h1, h2, h3 { +h1, h2, h3, .index-title, .index-subtitle { line-height:1.1; } -h1 { +h1, .index-title { font-size:28px; font-weight: 500; } @@ -28,11 +28,15 @@ h2 { font-weight: 500; } -h3, h4, h5, h6 { +h3, h4, h5, h6, .index-subtitle { color:#494949; font-weight: 500; } +.index-subtitle { + font-size: 1.17em; +} + a { color:#39c; text-decoration:none; diff --git a/webpages/vm-operator/VM-Operator.svg b/webpages/vm-operator/VM-Operator.svg index c8616d5..30c1ed2 100644 --- a/webpages/vm-operator/VM-Operator.svg +++ b/webpages/vm-operator/VM-Operator.svg @@ -7,7 +7,7 @@ viewBox="0 0 331.50461 323.22329" id="svg2" version="1.1" - inkscape:version="1.2.2 (b0a8486541, 2022-12-01)" + inkscape:version="1.3.2 (091e20ef0f, 2023-11-25)" sodipodi:docname="VM-Operator.svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" @@ -25,9 +25,9 @@ borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" - inkscape:zoom="0.7" - inkscape:cx="245" - inkscape:cy="145.71429" + inkscape:zoom="1.4" + inkscape:cx="190.35714" + inkscape:cy="178.57143" inkscape:document-units="px" inkscape:current-layer="layer1" showgrid="false" @@ -171,12 +171,12 @@ cy="-109.05605" r="9.2055216" /> + transform="matrix(0.32800241,0,0,0.32572486,-723.34527,-233.01684)"> diff --git a/webpages/vm-operator/admin-gui.md b/webpages/vm-operator/admin-gui.md index 15a6dec..4bfa3d3 100644 --- a/webpages/vm-operator/admin-gui.md +++ b/webpages/vm-operator/admin-gui.md @@ -1,5 +1,5 @@ --- -title: VM-Operator Web-GUI for Admins +title: "VM-Operator: Administrator View — Provides an overview of running VMs" layout: vm-operator --- diff --git a/webpages/vm-operator/controller.md b/webpages/vm-operator/controller.md index 2a00b16..a24943d 100644 --- a/webpages/vm-operator/controller.md +++ b/webpages/vm-operator/controller.md @@ -1,5 +1,5 @@ --- -title: VM-Operator Controller +title: "VM-Operator: Controller — Reconciles the VM CRs" layout: vm-operator --- diff --git a/webpages/vm-operator/favicon.svg b/webpages/vm-operator/favicon.svg index e216c44..c8616d5 100644 --- a/webpages/vm-operator/favicon.svg +++ b/webpages/vm-operator/favicon.svg @@ -2,23 +2,20 @@ + inkscape:version="1.2.2 (b0a8486541, 2022-12-01)" + sodipodi:docname="VM-Operator.svg" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns="http://www.w3.org/2000/svg" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:dc="http://purl.org/dc/elements/1.1/"> + inkscape:window-y="32" + inkscape:window-maximized="1" + fit-margin-top="0" + fit-margin-left="0" + fit-margin-right="0" + fit-margin-bottom="0" + inkscape:showpageshadow="2" + inkscape:pagecheckerboard="0" + inkscape:deskcolor="#d1d1d1" /> @@ -51,7 +51,6 @@ image/svg+xml - @@ -59,30 +58,127 @@ inkscape:label="Ebene 1" inkscape:groupmode="layer" id="layer1" - transform="translate(-175.34341,-117.71255)"> - M - L + transform="translate(799.83239,410.74206)"> + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/webpages/vm-operator/index-pic.svg b/webpages/vm-operator/index-pic.svg new file mode 100644 index 0000000..e912900 --- /dev/null +++ b/webpages/vm-operator/index-pic.svg @@ -0,0 +1,7329 @@ + + + + diff --git a/webpages/vm-operator/index.md b/webpages/vm-operator/index.md index 232a9ce..32d2cd5 100644 --- a/webpages/vm-operator/index.md +++ b/webpages/vm-operator/index.md @@ -1,13 +1,15 @@ --- -title: VM-Operator by mnlipp -description: A Kubernetes operator for running virtual machines (notably Qemu VMs) in pods on Kubernetes +title: Run Qemu based VMs on Kubernetes +description: A Kubernetes operator for running virtual machines (notably Qemu VMs) in pods on Kubernetes with a web interface for admins and users. layout: vm-operator --- # Welcome to VM-Operator -The goal of this project is to provide the means for running Qemu -based VMs in Kubernetes pods. +![Overview picture](index-pic.svg) + +The goal of this project is to provide easy to use and flexible components +for running Qemu based VMs in Kubernetes pods. The image used for the VM pods combines Qemu and a control program for starting and managing the Qemu process. This application is called diff --git a/webpages/vm-operator/manager.md b/webpages/vm-operator/manager.md index 4613201..8e6ebb4 100644 --- a/webpages/vm-operator/manager.md +++ b/webpages/vm-operator/manager.md @@ -1,5 +1,5 @@ --- -title: VM-Operator Manager +title: "VM-Operator: The Manager — Provides the controller and a web user interface" layout: vm-operator --- @@ -7,7 +7,7 @@ layout: vm-operator The Manager is the program that provides the controller from the [operator pattern](https://github.com/cncf/tag-app-delivery/blob/eece8f7307f2970f46f100f51932db106db46968/operator-wg/whitepaper/Operator-WhitePaper_v1-0.md#operator-components-in-kubernetes) -together with a Web-GUI. It should be run in a container in the cluster. +together with a web user interface. It should be run in a container in the cluster. ## Installation diff --git a/webpages/vm-operator/runner.md b/webpages/vm-operator/runner.md index d580530..319a5dc 100644 --- a/webpages/vm-operator/runner.md +++ b/webpages/vm-operator/runner.md @@ -1,5 +1,5 @@ --- -title: VM-Operator Runner +title: "VM-Operator: The Runner — Starts and monitors a VM" layout: vm-operator --- diff --git a/webpages/vm-operator/upgrading.md b/webpages/vm-operator/upgrading.md index 41d04ad..7b69716 100644 --- a/webpages/vm-operator/upgrading.md +++ b/webpages/vm-operator/upgrading.md @@ -1,5 +1,5 @@ --- -title: Upgrading +title: "VM-Operator: Upgrading — Issues to watch out for" layout: vm-operator --- diff --git a/webpages/vm-operator/user-gui.md b/webpages/vm-operator/user-gui.md index 394c28f..ce46e8f 100644 --- a/webpages/vm-operator/user-gui.md +++ b/webpages/vm-operator/user-gui.md @@ -1,5 +1,5 @@ --- -title: VM-Operator Web-GUI for Users +title: "VM-Operator: User View — Allows users to manage their own VMs" layout: vm-operator --- @@ -99,7 +99,7 @@ spec: spice: port: 5930 server: 192.168.19.32 - proxyUrl: http://lgpe-spice.some.host:1234 + proxyUrl: http://vms-spice.some.host:1234 generateSecret: true ``` diff --git a/webpages/vm-operator/webgui.md b/webpages/vm-operator/webgui.md index 38b9faa..1dbb20f 100644 --- a/webpages/vm-operator/webgui.md +++ b/webpages/vm-operator/webgui.md @@ -1,11 +1,11 @@ --- -title: VM-Operator Web-GUI +title: "VM-Operator: Web user interface — Provides easy access to VM management" layout: vm-operator --- -# The Web-GUI +# Web user interface -The manager component provides a GUI via a web server. The web GUI is +The manager component provides a GUI via a web server. This web user interface is implemented using components from the [JGrapes WebConsole](https://jgrapes.org/WebConsole.html) project. Configuration of the GUI therefore follows the conventions @@ -31,7 +31,7 @@ from the ## User Access -Access to the web GUI is controlled by the login conlet. The framework +Access to the web user interface is controlled by the login conlet. The framework does not include sophisticated components for user management. Rather, it assumes that an OIDC provider is responsible for user authentication and role management.