diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml
index f47366a..547c1a4 100644
--- a/.github/workflows/gradle.yml
+++ b/.github/workflows/gradle.yml
@@ -22,10 +22,10 @@ jobs:
fetch-depth: 0
- name: Install graphviz
run: sudo apt-get install graphviz
- - name: Set up JDK 21
+ - name: Set up JDK 17
uses: actions/setup-java@v3
with:
- java-version: '21'
+ java-version: '17'
distribution: 'temurin'
- name: Build with Gradle
- run: ./gradlew -Pwebsite.push.token=${{ secrets.WEBSITE_PUSH_TOKEN }} stage
+ run: ./gradlew -Prepo.access.token=${{ secrets.REPO_ACCESS_TOKEN }} stage
diff --git a/.github/workflows/jekyll.yml b/.github/workflows/jekyll.yml
deleted file mode 100644
index d0e4ec9..0000000
--- a/.github/workflows/jekyll.yml
+++ /dev/null
@@ -1,89 +0,0 @@
-# This workflow uses actions that are not certified by GitHub.
-# They are provided by a third-party and are governed by
-# separate terms of service, privacy policy, and support
-# documentation.
-
-# Sample workflow for building and deploying a Jekyll site to GitHub Pages
-name: Deploy Jekyll site to Pages
-
-on:
- # Runs on pushes targeting the default branch
- push:
- branches: ["main"]
-
- # Allows you to run this workflow manually from the Actions tab
- workflow_dispatch:
-
-# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
-permissions:
- contents: read
- pages: write
- id-token: write
-
-# Allow only one concurrent deployment, skipping runs queued between
-# the run in-progress and latest queued. However, do NOT cancel
-# in-progress runs as we want to allow these production deployments
-# to complete.
-concurrency:
- group: "pages"
- cancel-in-progress: false
-
-jobs:
- # Build job
- build:
- runs-on: ubuntu-latest
- steps:
- - name: Checkout
- uses: actions/checkout@v4
- with:
- fetch-depth: 0
- - name: Setup Ruby
- uses: ruby/setup-ruby@v1
- with:
- ruby-version: '3.3' # Not needed with a .ruby-version file
- bundler-cache: true # runs 'bundle install' and caches installed gems automatically
- cache-version: 0 # Increment this number if you need to re-download cached gems
- working-directory: webpages
- - name: Setup Pages
- id: pages
- uses: actions/configure-pages@v5
- - name: Build with Jekyll
- # Outputs to the './_site' directory by default
- run: cd webpages && bundle exec jekyll build
- env:
- JEKYLL_ENV: production
- - name: Install graphviz
- run: sudo apt-get install graphviz
- - name: Set up JDK 21
- uses: actions/setup-java@v3
- with:
- java-version: '21'
- distribution: 'temurin'
- - name: Build apidocs
- run: ./gradlew apidocs
- - name: Copy javadoc
- run: cp -a build/javadoc webpages/_site/
- - name: Generate the sitemap
- uses: cicirello/generate-sitemap@v1
- with:
- path-to-root: webpages/_site
- base-url-path: https://vm-operator.jdrupes.org
- - name: Index pagefind
- run: cd webpages && npx pagefind --source "_site"
- - name: Upload artifact
- # Automatically uploads an artifact from the './_site' directory by default
- uses: actions/upload-pages-artifact@v3
- with:
- path: './webpages/_site'
-
- # Deployment job
- deploy:
- environment:
- name: github-pages
- url: ${{ steps.deployment.outputs.page_url }}
- runs-on: ubuntu-latest
- needs: build
- steps:
- - name: Deploy to GitHub Pages
- id: deployment
- uses: actions/deploy-pages@v4
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index beab0c4..e99ee03 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -31,10 +31,10 @@ jobs:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- - name: Set up JDK 21
+ - name: Set up JDK 17
uses: actions/setup-java@v3
with:
- java-version: '21'
+ java-version: '17'
distribution: 'temurin'
- name: Push with Gradle
- run: ./gradlew -Pwebsite.push.token=${{ secrets.WEBSITE_PUSH_TOKEN }} -Pdocker.registry=ghcr.io/${{ github.actor }} stage publishImage
+ run: ./gradlew -Prepo.access.token=${{ secrets.REPO_ACCESS_TOKEN }} -Pdocker.registry=ghcr.io/${{ github.actor }} stage pushImages
diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
new file mode 100644
index 0000000..70654cc
--- /dev/null
+++ b/.gitlab-ci.yml
@@ -0,0 +1,28 @@
+default:
+ # Template project: https://gitlab.com/pages/jekyll
+ # Docs: https://docs.gitlab.com/ee/pages/
+ image: ruby:3.2
+ before_script:
+ - git fetch origin gh-pages
+ - git checkout gh-pages
+ - gem install bundler
+ - bundle install
+variables:
+ JEKYLL_ENV: production
+ LC_ALL: C.UTF-8
+test:
+ stage: test
+ script:
+ - bundle exec jekyll build -d test
+ artifacts:
+ paths:
+ - test
+
+pages:
+ stage: deploy
+ script:
+ - bundle exec jekyll build -d public
+ artifacts:
+ paths:
+ - public
+ environment: production
diff --git a/.markdownlint.yaml b/.markdownlint.yaml
deleted file mode 100644
index 6ed5002..0000000
--- a/.markdownlint.yaml
+++ /dev/null
@@ -1,30 +0,0 @@
-# See [rules](https://github.com/DavidAnson/markdownlint/blob/main/schema/.markdownlint.yaml)
-
-# Default state for all rules
-default: true
-
-# MD007/ul-indent : Unordered list indentation :
-# https://github.com/DavidAnson/markdownlint/blob/v0.37.4/doc/md007.md
-MD007:
- # Spaces for indent
- indent: 2
- # Whether to indent the first level of the list
- start_indented: true
- # Spaces for first level indent (when start_indented is set)
- start_indent: 2
-
-# MD025/single-title/single-h1 : Multiple top-level headings in the same document :
-# https://github.com/DavidAnson/markdownlint/blob/v0.37.4/doc/md025.md
-MD025:
- # Heading level
- level: 1
- # RegExp for matching title in front matter (disable)
- front_matter_title: ""
-
-# MD036/no-emphasis-as-heading : Emphasis used instead of a heading :
-# https://github.com/DavidAnson/markdownlint/blob/v0.37.4/doc/md036.md
-MD036: false
-
-# MD043/required-headings : Required heading structure :
-# https://github.com/DavidAnson/markdownlint/blob/v0.37.4/doc/md043.md
-MD043: false
diff --git a/.woodpecker/build.yaml b/.woodpecker/build.yaml
deleted file mode 100644
index 56a575c..0000000
--- a/.woodpecker/build.yaml
+++ /dev/null
@@ -1,38 +0,0 @@
-when:
-- event: push
- evaluate: 'CI_SYSTEM_HOST == "woodpecker.mnl.de"'
-
-clone:
-- name: git
- image: woodpeckerci/plugin-git
- settings:
- partial: false
- tags: true
- depth: 0
-
-steps:
-- name: prepare
- image: alpine
- commands:
- # Because we run the next step as user 1000 to make podman work:
- - mkdir /woodpecker/workflow
- - chown 1000:1000 /woodpecker/workflow
- - chown -R 1000:1000 $CI_WORKSPACE
-
-- name: build-jars
- image: registry.mnl.de/mnl/jdk21-builder:v4
- environment:
- HOME: /woodpecker/workflow
- REGISTRY: registry.mnl.de
- REGISTRY_USER: mnl
- REGISTRY_TOKEN:
- from_secret: REGISTRY_TOKEN
- commands:
- - echo $REGISTRY_TOKEN | podman login -u $REGISTRY_USER --password-stdin $REGISTRY
- - ./gradlew -Pdocker.registry=$REGISTRY/$REGISTRY_USER build apidocs publishImage
- backend_options:
- kubernetes:
- securityContext:
- privileged: true
- runAsUser: 1000
- runAsGroup: 1000
diff --git a/README.md b/README.md
index 09fcd25..176437a 100644
--- a/README.md
+++ b/README.md
@@ -3,23 +3,10 @@


-# Run QEMU/KVM in Kubernetes Pods
+# Run Qemu in Kubernetes Pods
-
+The goal of this project is to provide the means for running Qemu
+based VMs in Kubernetes pods.
-This project provides an easy to use and flexible solution for running
-QEMU/KVM based VMs in Kubernetes pods.
-
-The central component of this solution is the kubernetes operator that
-manages "runners". These run in pods and are used to start and manage
-the QEMU/KVM process for the VMs (optionally together with a SW-TPM).
-
-A web GUI for administrators provides an overview of the VMs together
-with some basic control over the VMs. A web GUI for users provides an
-interface to access and optionally start, stop and reset the VMs.
-
-Advanced features of the operator include pooling of VMs and automatic
-login.
-
-See the [project's home page](https://vm-operator.jdrupes.org/)
+See the [project's home page](https://mnlipp.github.io/VM-Operator/)
for details.
diff --git a/build.gradle b/build.gradle
index eb8e59a..1a11881 100644
--- a/build.gradle
+++ b/build.gradle
@@ -5,10 +5,9 @@ buildscript {
}
plugins {
- id 'org.ajoberstar.grgit' version '5.2.0'
+ 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.17.2' apply false
- id 'org.jdrupes.vmoperator.versioning-conventions'
+ id 'pl.allegro.tech.build.axion-release' version '1.15.0' apply false
id 'org.jdrupes.vmoperator.java-doc-conventions'
id 'eclipse'
id "com.github.node-gradle.node" version "7.0.1"
@@ -19,7 +18,7 @@ allprojects {
}
task stage {
- description = 'To be executed by CI.'
+ description = 'To be executed by CI, build and update JavaDoc.'
group = 'build'
// Build everything first
@@ -27,6 +26,11 @@ task stage {
dependsOn subprojects.tasks.collect {
tc -> tc.findByName("build") }.flatten()
}
+
+ if (JavaVersion.current() == JavaVersion.VERSION_17) {
+ // Publish JavaDoc
+ dependsOn gitPublishPush
+ }
}
eclipse {
diff --git a/buildSrc/.settings/org.eclipse.jdt.core.prefs b/buildSrc/.settings/org.eclipse.jdt.core.prefs
index b25073a..68fda12 100644
--- a/buildSrc/.settings/org.eclipse.jdt.core.prefs
+++ b/buildSrc/.settings/org.eclipse.jdt.core.prefs
@@ -1,7 +1,9 @@
-#
-#Wed Oct 02 14:48:43 CEST 2024
eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
+org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
+org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.methodParameters=do not generate
org.eclipse.jdt.core.compiler.codegen.targetPlatform=21
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.compliance=21
@@ -9,5 +11,12 @@ org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
+org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
+org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.source=21
diff --git a/buildSrc/.settings/org.eclipse.jdt.groovy.core.prefs b/buildSrc/.settings/org.eclipse.jdt.groovy.core.prefs
index 71b5e37..bf0ca13 100644
--- a/buildSrc/.settings/org.eclipse.jdt.groovy.core.prefs
+++ b/buildSrc/.settings/org.eclipse.jdt.groovy.core.prefs
@@ -1,3 +1,3 @@
eclipse.preferences.version=1
-groovy.compiler.level=-1
+groovy.compiler.level=40
groovy.script.filters=**/*.dsld,y,**/*.gradle,n
diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle
index 4a5db6d..a9fb634 100644
--- a/buildSrc/build.gradle
+++ b/buildSrc/build.gradle
@@ -1,3 +1,9 @@
+/*
+ * This file was generated by the Gradle 'init' task.
+ *
+ * This project uses @Incubating APIs which are subject to change.
+ */
+
plugins {
// Support convention plugins written in Groovy. Convention plugins
// are build scripts in 'src/main' that automatically become available
@@ -8,24 +14,52 @@ plugins {
id 'eclipse'
}
+repositories {
+ // Use the plugin portal to apply community plugins in convention plugins.
+ gradlePluginPortal()
+}
+
sourceSets {
- main {
- groovy {
- srcDirs = ['src']
- }
- resources {
- srcDirs = ['resources']
- }
- }
+ main {
+ groovy {
+ srcDirs = ['src']
+ }
+ }
+
+ test {
+ groovy {
+ srcDirs = ['test']
+ }
+ }
}
eclipse {
+ project {
+ file {
+ // closure executed after .project content is loaded from existing file
+ // and before gradle build information is merged
+ beforeMerged { project ->
+ project.natures.clear()
+ project.buildCommands.clear()
+ }
+
+ project.natures += 'org.eclipse.buildship.core.gradleprojectnature'
+ // Don't build, result not used by Eclipse anyway
+ // project.buildCommand 'org.eclipse.buildship.core.gradleprojectbuilder'
+ }
+ }
+
+ classpath {
+ downloadJavadoc = true
+ downloadSources = true
+ }
+
jdt {
file {
withProperties { properties ->
def formatterPrefs = new Properties()
- rootProject.file("../gradle/org.eclipse.jdt.core.formatter.prefs")
+ rootProject.file("gradle/org.eclipse.jdt.core.formatter.prefs")
.withInputStream { formatterPrefs.load(it) }
properties.putAll(formatterPrefs)
}
diff --git a/buildSrc/settings.gradle b/buildSrc/settings.gradle
new file mode 100644
index 0000000..3f67e42
--- /dev/null
+++ b/buildSrc/settings.gradle
@@ -0,0 +1,7 @@
+/*
+ * This file was generated by the Gradle 'init' task.
+ *
+ * This settings file is used to specify which projects to include in your build-logic build.
+ */
+
+rootProject.name = 'buildSrc'
diff --git a/buildSrc/src/org.jdrupes.vmoperator.java-common-conventions.gradle b/buildSrc/src/org.jdrupes.vmoperator.java-common-conventions.gradle
index 605dc09..c7419fa 100644
--- a/buildSrc/src/org.jdrupes.vmoperator.java-common-conventions.gradle
+++ b/buildSrc/src/org.jdrupes.vmoperator.java-common-conventions.gradle
@@ -55,7 +55,7 @@ sourceSets {
java {
toolchain {
- languageVersion = JavaLanguageVersion.of(21)
+ languageVersion = JavaLanguageVersion.of(17)
}
}
diff --git a/buildSrc/src/org.jdrupes.vmoperator.java-doc-conventions.gradle b/buildSrc/src/org.jdrupes.vmoperator.java-doc-conventions.gradle
index 6af8fa7..95d7eff 100644
--- a/buildSrc/src/org.jdrupes.vmoperator.java-doc-conventions.gradle
+++ b/buildSrc/src/org.jdrupes.vmoperator.java-doc-conventions.gradle
@@ -22,28 +22,31 @@ configurations {
}
dependencies {
- markdownDoclet "org.jdrupes.mdoclet:doclet:4.0.0"
- javadocTaglets "org.jdrupes.taglets:plantuml-taglet:3.0.0"
+ markdownDoclet "org.jdrupes.mdoclet:doclet:3.1.0"
+ javadocTaglets "org.jdrupes.taglets:plantuml-taglet:2.1.0"
+}
+
+task javadocResources(type: Copy) {
+ into file(docDestinationDir)
+ from ("${rootProject.rootDir}/misc") {
+ include '*.woff2'
+ }
}
task apidocs (type: JavaExec) {
// Does not work on JitPack, no /usr/bin/dot
- enabled = JavaVersion.current() == JavaVersion.VERSION_21
+ enabled = JavaVersion.current() == JavaVersion.VERSION_17
+
+ dependsOn javadocResources
outputs.dir(docDestinationDir)
inputs.file rootProject.file('overview.md')
- inputs.file "${rootProject.rootDir}/misc/javadoc-overwrites.css"
+ inputs.file "${rootProject.rootDir}/misc/stylesheet.css"
- jvmArgs = ['--add-exports=jdk.compiler/com.sun.tools.doclint=ALL-UNNAMED',
- '--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED',
- '--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED',
- '--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED',
- '--add-exports=jdk.javadoc/jdk.javadoc.internal.tool=ALL-UNNAMED',
- '--add-exports=jdk.javadoc/jdk.javadoc.internal.doclets.toolkit=ALL-UNNAMED',
- '--add-opens=jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.resources.releases=ALL-UNNAMED',
- '-Duser.language=en', '-Duser.region=US']
- mainClass = 'jdk.javadoc.internal.tool.Main'
+ jvmArgs = ['--add-exports=jdk.javadoc/jdk.javadoc.internal.tool=ALL-UNNAMED',
+ '--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED']
+ main = 'jdk.javadoc.internal.tool.Main'
gradle.projectsEvaluated {
// Make sure that other projects' compileClasspaths are resolved
@@ -66,8 +69,8 @@ task apidocs (type: JavaExec) {
'-package',
'-use',
'-linksource',
- '-link', 'https://docs.oracle.com/en/java/javase/21/docs/api/',
- '-link', 'https://jgrapes.org/latest-release/javadoc/',
+ '-link', 'https://docs.oracle.com/en/java/javase/17/docs/api/',
+ '-link', 'https://mnlipp.github.io/jgrapes/latest-release/javadoc/',
'-link', 'https://freemarker.apache.org/docs/api/',
'--add-exports', 'jdk.javadoc/jdk.javadoc.internal.tool=ALL-UNNAMED',
'--add-exports', 'jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED',
@@ -85,7 +88,7 @@ task apidocs (type: JavaExec) {
'-bottom', rootProject.file("misc/javadoc.bottom.txt").text,
'--allow-script-in-comments',
'-Xdoclint:-html',
- '--add-stylesheet', "${rootProject.rootDir}/misc/javadoc-overwrites.css",
+ '--main-stylesheet', "${rootProject.rootDir}/misc/stylesheet.css",
'--add-exports=jdk.javadoc/jdk.javadoc.internal.doclets.formats.html=ALL-UNNAMED',
'-quiet'
]
@@ -94,27 +97,34 @@ task apidocs (type: JavaExec) {
ignoreExitValue true
}
-task testJavadoc(type: Javadoc) {
- enabled = JavaVersion.current() == JavaVersion.VERSION_21
-
- source = fileTree(dir: 'testfiles', include: '**/*.java')
- destinationDir = project.file("build/testfiles-gradle")
- options.docletpath = configurations.markdownDoclet.files.asType(List)
- options.doclet = 'org.jdrupes.mdoclet.MDoclet'
- options.overview = 'testfiles/overview.md'
- options.addStringOption('Xdoclint:-html', '-quiet')
-
- options.setJFlags([
- '--add-exports=jdk.compiler/com.sun.tools.doclint=ALL-UNNAMED',
- '--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED',
- '--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED',
- '--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED',
- '--add-exports=jdk.javadoc/jdk.javadoc.internal.tool=ALL-UNNAMED',
- '--add-exports=jdk.javadoc/jdk.javadoc.internal.doclets.toolkit=ALL-UNNAMED',
- '--add-opens=jdk.javadoc/jdk.javadoc.internal.doclets.toolkit.resources.releases=ALL-UNNAMED'])
-}
// Prepare github authentication for plugins
if (System.properties['org.ajoberstar.grgit.auth.username'] == null) {
System.setProperty('org.ajoberstar.grgit.auth.username',
- project.rootProject.properties['website.push.token'] ?: "nouser")
+ project.rootProject.properties['repo.access.token'] ?: "nouser")
+}
+
+gitPublish {
+ repoUri = 'https://github.com/mnlipp/VM-Operator.git'
+ branch = 'gh-pages'
+ contents {
+ from("${rootProject.buildDir}/javadoc") {
+ into 'javadoc'
+ }
+ if (!findProject(':org.jdrupes.vmoperator.runner.qemu').isSnapshot
+ && !findProject(':org.jdrupes.vmoperator.manager').isSnapshot) {
+ from("${rootProject.buildDir}/javadoc") {
+ into 'latest-release/javadoc'
+ }
+ }
+ }
+ preserve { include '**/*' }
+ commitMessage = "Updated."
+}
+
+gradle.projectsEvaluated {
+ tasks.gitPublishReset.mustRunAfter subprojects.tasks
+ .collect { tc -> tc.findByName("build") }.flatten()
+ tasks.gitPublishReset.mustRunAfter subprojects.tasks
+ .collect { tc -> tc.findByName("test") }.flatten()
+ tasks.gitPublishCopy.dependsOn apidocs
}
diff --git a/buildSrc/src/org.jdrupes.vmoperator.versioning-conventions.gradle b/buildSrc/src/org.jdrupes.vmoperator.versioning-conventions.gradle
index 49b6f74..a9e8dfe 100644
--- a/buildSrc/src/org.jdrupes.vmoperator.versioning-conventions.gradle
+++ b/buildSrc/src/org.jdrupes.vmoperator.versioning-conventions.gradle
@@ -19,7 +19,6 @@ if (shortened == "manager") {
var tagName = shortened.replace('.', '-') + "-"
if (grgit.branch.current.name != "main"
&& grgit.branch.current.name != "HEAD"
- && !grgit.branch.current.name.startsWith("testing")
&& !grgit.branch.current.name.startsWith("release")
&& !grgit.branch.current.name.startsWith("develop")) {
tagName = tagName + grgit.branch.current.name.replace('/', '-') + "-"
diff --git a/deploy/crds/vmpools-crd.yaml b/deploy/crds/vmpools-crd.yaml
deleted file mode 100644
index 2144940..0000000
--- a/deploy/crds/vmpools-crd.yaml
+++ /dev/null
@@ -1,74 +0,0 @@
-apiVersion: apiextensions.k8s.io/v1
-kind: CustomResourceDefinition
-metadata:
- name: vmpools.vmoperator.jdrupes.org
-spec:
- group: vmoperator.jdrupes.org
- # list of versions supported by this CustomResourceDefinition
- versions:
- - name: v1
- served: true
- storage: true
- schema:
- openAPIV3Schema:
- type: object
- properties:
- spec:
- type: object
- properties:
- retention:
- description: >-
- Defines the timeout for assignments. The time may be
- specified as ISO 8601 time or duration. When specifying
- a duration, it will be added to the last time the VM's
- console was used to obtain the timeout.
- type: string
- pattern: '^(?:\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])T(?:[01]\d|2[0-3]):[0-5]\d:[0-5]\d(?:\.\d{1,9})?(?:Z|[+-](?:[01]\d|2[0-3])(?:|:?[0-5]\d))|P(?:\d+Y)?(?:\d+M)?(?:\d+W)?(?:\d+D)?(?:T(?:\d+[Hh])?(?:\d+[Mm])?(?:\d+(?:\.\d{1,9})?[Ss])?)?)$'
- default: "PT1h"
- loginOnAssignment:
- description: >-
- If set to true, the user will be automatically logged in
- to the VM's console when the VM is assigned to him.
- type: boolean
- default: false
- permissions:
- type: array
- description: >-
- Defines permissions for accessing and manipulating the Pool.
- items:
- type: object
- description: >-
- Permissions can be granted to a user or to a role.
- oneOf:
- - required:
- - user
- - required:
- - role
- properties:
- user:
- type: string
- role:
- type: string
- may:
- type: array
- items:
- type: string
- enum:
- - start
- - stop
- - reset
- - accessConsole
- - "*"
- default: ["accessConsole"]
- required:
- - permissions
- # either Namespaced or Cluster
- scope: Namespaced
- names:
- # plural name to be used in the URL: /apis///
- plural: vmpools
- # singular name to be used as an alias on the CLI and for display
- singular: vmpool
- # kind is normally the CamelCased singular type. Your resource manifests use this.
- kind: VmPool
- listKind: VmPoolList
diff --git a/deploy/crds/vms-crd.yaml b/deploy/crds/vms-crd.yaml
index c2a7a66..bfe3985 100644
--- a/deploy/crds/vms-crd.yaml
+++ b/deploy/crds/vms-crd.yaml
@@ -994,10 +994,6 @@ spec:
type: array
description: >-
Defines permissions for accessing and manipulating the VM.
- The meaning of most permissions should be obvious. The
- difference between "accessConsole" and "takeConsole" is
- that "takeConsole" allows the user to take control of
- the console even if it is already in use by another user.
items:
type: object
description: >-
@@ -1021,21 +1017,8 @@ spec:
- stop
- reset
- accessConsole
- - takeConsole
- "*"
default: []
- pools:
- type: array
- description: >-
- List of pools this VM belongs to.
- items:
- type: string
- default: []
- loggingProperties:
- type: string
- description: >-
- Override the default logging properties for
- the runner for this VM.
vm:
type: object
description: Defines the VM.
@@ -1427,15 +1410,6 @@ spec:
display:
type: object
properties:
- outputs:
- type: integer
- default: 1
- loggedInUser:
- description: >-
- The name of a user that should be automatically
- logged in on the display. Note that this requires
- support from an agent in the guest OS.
- type: string
spice:
type: object
properties:
@@ -1470,10 +1444,6 @@ spec:
type: object
default: {}
properties:
- runnerVersion:
- description: >-
- The version string of the runner.
- type: string
cpus:
description: >-
Number of CPUs currently in use.
@@ -1484,50 +1454,12 @@ spec:
Amount of memory in use.
type: string
default: "0"
- consoleClient:
- description: >-
- The hostname of the currently connected client.
- type: string
- default: ""
- consoleUser:
- description: >-
- The id of the user who has last requested a console
- connection.
- type: string
- default: ""
- loggedInUser:
- description: >-
- The name of a user that is currently logged in by the
- VM operator agent.
- type: string
displayPasswordSerial:
description: >-
Counts changes of the display password. Set to -1
by the runner if password protection is not enabled.
type: integer
default: 0
- osinfo:
- description: Copy of the OS info provided by the guest agent.
- type: object
- x-kubernetes-preserve-unknown-fields: true
- assignment:
- description: >-
- The assignment of this VM to a a particular user.
- type: object
- properties:
- pool:
- description: >-
- The pool this VM is taken from.
- type: string
- user:
- description: >-
- The user this VM is assigned to.
- type: string
- lastUsed:
- description: >-
- The last time this VM was used by the user.
- type: string
- default: {}
conditions:
description: >-
List of component conditions observed
@@ -1538,30 +1470,6 @@ 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
- lastTransitionTime: "1970-01-01T00:00:00Z"
- reason: Creation
- message: "Creation of CR"
type: array
items:
type: object
diff --git a/deploy/vmop-deployment.yaml b/deploy/vmop-deployment.yaml
index 08316f6..63b3d1e 100644
--- a/deploy/vmop-deployment.yaml
+++ b/deploy/vmop-deployment.yaml
@@ -20,32 +20,23 @@ spec:
containers:
- name: vm-operator
image: >-
- ghcr.io/mnlipp/org.jdrupes.vmoperator.manager:latest
- imagePullPolicy: Always
- env:
- - name: JAVA_OPTS
- # The VM operator needs about 25 MB of memory, plus 1 MB for
- # each VM. The reason is that for the sake of effeciency, we
- # have to keep a parsed representation of the CRD in memory,
- # which requires about 512 KB per VM. While handling updates,
- # we temporarily have the old and the new version of the CRD
- # in memory, so we need another 512 KB per VM.
- value: "-Xmx128m"
- resources:
- requests:
- cpu: 100m
- memory: 128Mi
+ ghcr.io/mnlipp/org.jdrupes.vmoperator.manager:3.0.0
volumeMounts:
- name: config
mountPath: /etc/opt/vmoperator
- name: vmop-image-repository
mountPath: /var/local/vmop-image-repository
+ imagePullPolicy: Always
securityContext:
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
allowPrivilegeEscalation: false
+ resources:
+ requests:
+ cpu: 100m
+ memory: 128Mi
volumes:
- name: config
configMap:
diff --git a/deploy/vmop-role.yaml b/deploy/vmop-role.yaml
index e1ae7bc..0b0e94a 100644
--- a/deploy/vmop-role.yaml
+++ b/deploy/vmop-role.yaml
@@ -9,15 +9,8 @@ rules:
- vmoperator.jdrupes.org
resources:
- vms
- - vmpools
verbs:
- '*'
-- apiGroups:
- - vmoperator.jdrupes.org
- resources:
- - vms/status
- verbs:
- - patch
- apiGroups:
- apps
resources:
@@ -35,12 +28,9 @@ rules:
- apiGroups:
- ""
resources:
- - persistentvolumeclaims
- pods
verbs:
- - watch
- list
- get
- - create
- delete
- patch
diff --git a/dev-example/.gitignore b/dev-example/.gitignore
index 1e31cc5..925478d 100644
--- a/dev-example/.gitignore
+++ b/dev-example/.gitignore
@@ -1,4 +1 @@
/test-vm-ci.yaml
-/kubeconfig.yaml
-/crds/
-/.vm-operator-cmd.rc
diff --git a/dev-example/Readme.md b/dev-example/Readme.md
index d794b24..516fb7e 100644
--- a/dev-example/Readme.md
+++ b/dev-example/Readme.md
@@ -1,11 +1,11 @@
# Example setup for development
The CRD must be deployed independently. Apart from that, the
-`kustomize.yaml`
+`kustomize.yaml`
- * creates a small cdrom image repository and
+* creates a small cdrom image repository and
- * deploys the operator in namespace `vmop-dev` with a replica of 0.
+* deploys the operator in namespace `vmop-dev` with a replica of 0.
This allows you to run the manager in your IDE.
diff --git a/dev-example/config.yaml b/dev-example/config.yaml
index 2a72bc8..579103d 100644
--- a/dev-example/config.yaml
+++ b/dev-example/config.yaml
@@ -7,28 +7,8 @@
"/Controller":
namespace: vmop-dev
"/Reconciler":
- runnerDataPvc:
- storageClassName: rook-cephfs
- loadBalancerService:
- labels:
- label1: label1
- label2: toBeReplaced
- annotations:
- metallb.universe.tf/loadBalancerIPs: 192.168.168.1
- metallb.universe.tf/ip-allocated-from-pool: single-common
- metallb.universe.tf/allow-shared-ip: single-common
- loggingProperties: |
- # Defaults for namespace (VM domain)
- handlers=java.util.logging.ConsoleHandler
-
- #org.jgrapes.level=FINE
- #org.jgrapes.core.handlerTracking.level=FINER
-
- org.jdrupes.vmoperator.runner.qemu.level=FINEST
-
- java.util.logging.ConsoleHandler.level=ALL
- java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
- java.util.logging.SimpleFormatter.format=%1$tb %1$td %1$tT %4$s %5$s%6$s%n
+ runnerData:
+ storageClassName: null
"/GuiSocketServer":
port: 8888
"/GuiHttpServer":
@@ -37,33 +17,18 @@
"/WebConsole":
"/LoginConlet":
users:
- - name: admin
- fullName: Administrator
- password: "$2b$05$NiBd74ZGdplLC63ePZf1f.UtjMKkbQ23cQoO2OKOFalDBHWAOy21."
- - name: operator
- fullName: Operator
- password: "$2b$05$hZaI/jToXf/d3BctZdT38Or7H7h6Pn2W3WiB49p5AyhDHFkkYCvo2"
- - name: test1
- fullName: Test Account 1
- password: "$2b$05$hZaI/jToXf/d3BctZdT38Or7H7h6Pn2W3WiB49p5AyhDHFkkYCvo2"
- - name: test2
- fullName: Test Account 2
- password: "$2b$05$hZaI/jToXf/d3BctZdT38Or7H7h6Pn2W3WiB49p5AyhDHFkkYCvo2"
- - name: test3
- fullName: Test Account 3
- password: "$2b$05$hZaI/jToXf/d3BctZdT38Or7H7h6Pn2W3WiB49p5AyhDHFkkYCvo2"
+ - name: admin
+ fullName: Administrator
+ password: "$2b$05$NiBd74ZGdplLC63ePZf1f.UtjMKkbQ23cQoO2OKOFalDBHWAOy21."
+ - name: test
+ fullName: Test Account
+ password: "$2b$05$hZaI/jToXf/d3BctZdT38Or7H7h6Pn2W3WiB49p5AyhDHFkkYCvo2"
"/RoleConfigurator":
rolesByUser:
# User admin has role admin
admin:
- admin
- operator:
- - operator
- test1:
- - user
- test2:
- - user
- test3:
+ test:
- user
# All users have role other
"*":
@@ -74,16 +39,13 @@
# Admins can use all conlets
admin:
- "*"
- operator:
- - org.jdrupes.vmoperator.vmmgmt.VmMgmt
- - org.jdrupes.vmoperator.vmaccess.VmAccess
user:
- - org.jdrupes.vmoperator.vmaccess.VmAccess
+ - org.jdrupes.vmoperator.vmviewer.VmViewer
# Others cannot use any conlet (except login conlet to log out)
other:
- org.jgrapes.webconlet.oidclogin.LoginConlet
"/ComponentCollector":
- "/VmAccess":
+ "/VmViewer":
displayResource:
preferredIpVersion: ipv4
syncPreviewsFor:
diff --git a/dev-example/gen-pool-vm-crds b/dev-example/gen-pool-vm-crds
deleted file mode 100755
index f9cf692..0000000
--- a/dev-example/gen-pool-vm-crds
+++ /dev/null
@@ -1,47 +0,0 @@
-#!/bin/bash
-
-function usage() {
- cat >&2 <&2 "Unknown option: $1"; exit 1;;
- *) template="$1";;
- esac
- shift
-done
-
-if [ -z "$template" ]; then
- usage
-fi
-
-if [ "$count" = "0" ]; then
- exit 0
-fi
-for number in $(seq 1 $count); do
- if [ -z "$prefix" ]; then
- prefix=$(basename $template .tpl.yaml)
- fi
- name="$prefix$(printf %03d $number)"
- index=$(($number - 1))
- esh -o $destination/$name.yaml $template number=$number index=$index
-done
diff --git a/dev-example/kustomization.yaml b/dev-example/kustomization.yaml
index 975d95f..19b6295 100644
--- a/dev-example/kustomization.yaml
+++ b/dev-example/kustomization.yaml
@@ -35,14 +35,6 @@ patches:
"/Reconciler":
runnerData:
storageClassName: null
- loadBalancerService:
- labels:
- label1: label1
- label2: toBeReplaced
- annotations:
- metallb.universe.tf/loadBalancerIPs: 192.168.168.1
- metallb.universe.tf/ip-allocated-from-pool: single-common
- metallb.universe.tf/allow-shared-ip: single-common
"/GuiSocketServer":
port: 8888
"/GuiHttpServer":
@@ -51,28 +43,18 @@ patches:
"/WebConsole":
"/LoginConlet":
users:
- - name: admin
- fullName: Administrator
- password: "$2b$05$NiBd74ZGdplLC63ePZf1f.UtjMKkbQ23cQoO2OKOFalDBHWAOy21."
- - name: test1
- fullName: Test Account
- password: "$2b$05$hZaI/jToXf/d3BctZdT38Or7H7h6Pn2W3WiB49p5AyhDHFkkYCvo2"
- - name: test2
- fullName: Test Account
- password: "$2b$05$hZaI/jToXf/d3BctZdT38Or7H7h6Pn2W3WiB49p5AyhDHFkkYCvo2"
- - name: test3
- fullName: Test Account
- password: "$2b$05$hZaI/jToXf/d3BctZdT38Or7H7h6Pn2W3WiB49p5AyhDHFkkYCvo2"
+ admin:
+ fullName: Administrator
+ password: "$2b$05$NiBd74ZGdplLC63ePZf1f.UtjMKkbQ23cQoO2OKOFalDBHWAOy21."
+ test:
+ fullName: Test Account
+ password: "$2b$05$hZaI/jToXf/d3BctZdT38Or7H7h6Pn2W3WiB49p5AyhDHFkkYCvo2"
"/RoleConfigurator":
rolesByUser:
# User admin has role admin
admin:
- admin
- test1:
- - user
- test2:
- - user
- test3:
+ test:
- user
# All users have role other
"*":
@@ -89,7 +71,7 @@ patches:
other:
- org.jgrapes.webconlet.locallogin.LoginConlet
"/ComponentCollector":
- "/VmAccess":
+ "/VmViewer":
displayResource:
preferredIpVersion: ipv4
syncPreviewsFor:
diff --git a/dev-example/pool-action b/dev-example/pool-action
deleted file mode 100755
index bc8fbce..0000000
--- a/dev-example/pool-action
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/bin/bash
-
-function usage() {
- cat >&2 <&2 "Unknown option: $1"; exit 1;;
- *) if [ ! -v pool ]; then
- pool="$1"
- elif [ ! -v action ]; then
- action="$1"
- else
- usage
- fi;;
- esac
- shift
-done
-
-if [ ! -v pool -o ! -v "action" -o ! -v context ]; then
- echo >&2 "Missing arguments or context not set."
- echo >&2
- usage
-fi
-case "$action" in
- "start"|"stop"|"delete"|"delete-disks") ;;
- *) usage;;
-esac
-
-kubectl --context="$context" -n "$namespace" get vms -o json \
- | jq -r '.items[] | select(.spec.pools | contains(["'${pool}'"])) | .metadata.name' \
-| while read vmName; do
- case "$action" in
- start) kubectl --context="$context" -n "$namespace" patch vms "$vmName" \
- --type='merge' -p '{"spec":{"vm":{"state":"Running"}}}';;
- stop) kubectl --context="$context" -n "$namespace" patch vms "$vmName" \
- --type='merge' -p '{"spec":{"vm":{"state":"Stopped"}}}';;
- delete) kubectl --context="$context" -n "$namespace" delete vm/"$vmName";;
- delete-disks) kubectl --context="$context" -n "$namespace" delete \
- pvc -l app.kubernetes.io/instance="$vmName" ;;
- esac
-done
diff --git a/dev-example/test-pool.yaml b/dev-example/test-pool.yaml
deleted file mode 100644
index 497aaf7..0000000
--- a/dev-example/test-pool.yaml
+++ /dev/null
@@ -1,17 +0,0 @@
-apiVersion: "vmoperator.jdrupes.org/v1"
-kind: VmPool
-metadata:
- namespace: vmop-dev
- name: test-vms
-spec:
- retention: "PT1m"
- loginOnAssignment: true
- permissions:
- - user: admin
- may:
- - accessConsole
- - start
- - role: user
- may:
- - accessConsole
- - start
diff --git a/dev-example/test-vm-snapshot.yaml b/dev-example/test-vm-snapshot.yaml
deleted file mode 100644
index fd60a25..0000000
--- a/dev-example/test-vm-snapshot.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
----
-apiVersion: snapshot.storage.k8s.io/v1
-kind: VolumeSnapshot
-metadata:
- namespace: vmop-dev
- name: test-vm-system-disk-snapshot
-spec:
- volumeSnapshotClassName: csi-rbdplugin-snapclass
- source:
- persistentVolumeClaimName: test-vm-system-disk
diff --git a/dev-example/test-vm.tpl.yaml b/dev-example/test-vm.tpl.yaml
deleted file mode 100644
index 76adfba..0000000
--- a/dev-example/test-vm.tpl.yaml
+++ /dev/null
@@ -1,66 +0,0 @@
-apiVersion: "vmoperator.jdrupes.org/v1"
-kind: VirtualMachine
-metadata:
- namespace: vmop-dev
- name: test-vm<%= $(printf "%02d" ${number}) %>
- annotations:
- argocd.argoproj.io/sync-wave: "20"
-
-spec:
- image:
- source: ghcr.io/mnlipp/org.jdrupes.vmoperator.runner.qemu-arch:latest
-# source: registry.mnl.de/org/jdrupes/vm-operator/org.jdrupes.vmoperator.runner.qemu-arch:testing
-# source: docker-registry.lan.mnl.de/vmoperator/org.jdrupes.vmoperator.runner.qemu-arch:latest
- pullPolicy: Always
-
- runnerTemplate:
- update: true
-
- permissions:
- - role: admin
- may:
- - "*"
-
- guestShutdownStops: true
-
- cloudInit:
- metaData: {}
-
- pools:
- - test-vms
-
- vm:
- # state: Running
- bootMenu: true
- maximumCpus: 4
- currentCpus: 2
- maximumRam: 6Gi
- currentRam: 4Gi
-
- networks:
- # No bridge on TC1
- # - tap: {}
- - user: {}
-
- disks:
- - volumeClaimTemplate:
- metadata:
- name: system
- spec:
- storageClassName: ceph-rbd3slow
- dataSource:
- name: test-vm-system-disk-snapshot
- kind: VolumeSnapshot
- apiGroup: snapshot.storage.k8s.io
- accessModes:
- - ReadWriteOnce
- resources:
- requests:
- storage: 40Gi
- - cdrom:
- image: ""
- # image: https://download.fedoraproject.org/pub/fedora/linux/releases/38/Workstation/x86_64/iso/Fedora-Workstation-Live-x86_64-38-1.6.iso
-
- display:
- spice:
- port: <%= $((5910 + number)) %>
diff --git a/dev-example/test-vm.yaml b/dev-example/test-vm.yaml
index aa75bc3..4acbfe4 100644
--- a/dev-example/test-vm.yaml
+++ b/dev-example/test-vm.yaml
@@ -5,13 +5,17 @@ metadata:
name: test-vm
spec:
image:
- source: registry.mnl.de/org/jdrupes/vm-operator/org.jdrupes.vmoperator.runner.qemu-arch:testing
- pullPolicy: Always
+ repository: docker-registry.lan.mnl.de
+ path: vmoperator/org.jdrupes.vmoperator.runner.qemu-alpine
+ version: 3.0.0
permissions:
- - user: admin
- may:
- - "*"
+ - user: admin
+ may:
+ - "*"
+ - user: test
+ may:
+ - "accessConsole"
resources:
requests:
@@ -32,9 +36,8 @@ spec:
currentCpus: 4
networks:
- # No bridge on test cluster
- - user: {}
-
+ - tap:
+ mac: "02:16:3e:33:58:10"
disks:
- volumeClaimTemplate:
metadata:
@@ -58,5 +61,3 @@ spec:
spice:
port: 5810
generateSecret: true
-
- loadBalancerService: {}
diff --git a/dev-example/vmop-agent/99-vmop-agent.rules b/dev-example/vmop-agent/99-vmop-agent.rules
deleted file mode 100644
index 4a18472..0000000
--- a/dev-example/vmop-agent/99-vmop-agent.rules
+++ /dev/null
@@ -1,2 +0,0 @@
-SUBSYSTEM=="virtio-ports", ATTR{name}=="org.jdrupes.vmop_agent.0", \
- TAG+="systemd" ENV{SYSTEMD_WANTS}="vmop-agent.service"
diff --git a/dev-example/vmop-agent/gdm/PostLogin/Default b/dev-example/vmop-agent/gdm/PostLogin/Default
deleted file mode 100755
index 8a70890..0000000
--- a/dev-example/vmop-agent/gdm/PostLogin/Default
+++ /dev/null
@@ -1,3 +0,0 @@
-#!/bin/sh
-
-sed -i '/AutomaticLogin/d' /etc/gdm/custom.conf
diff --git a/dev-example/vmop-agent/vmop-agent b/dev-example/vmop-agent/vmop-agent
deleted file mode 100755
index 9f4d9e7..0000000
--- a/dev-example/vmop-agent/vmop-agent
+++ /dev/null
@@ -1,146 +0,0 @@
-#!/usr/bin/bash
-
-# Note that this script requires "jq" to be installed and a version
-# of loginctl that accepts the "-j" option.
-
-while [ "$#" -gt 0 ]; do
- case "$1" in
- --path) shift; ttyPath="$1";;
- --path=*) IFS='=' read -r option value <<< "$1"; ttyPath="$value";;
- esac
- shift
-done
-
-ttyPath="${ttyPath:-/dev/virtio-ports/org.jdrupes.vmop_agent.0}"
-
-if [ ! -w "$ttyPath" ]; then
- echo >&2 "Device $ttyPath not writable"
- exit 1
-fi
-
-# Create fd for the tty in variable con
-if ! exec {con}<>"$ttyPath"; then
- echo >&2 "Cannot open device $ttyPath"
- exit 1
-fi
-
-# Temporary file for logging error messages, clear tty and signal ready
-temperr=$(mktemp)
-clear >/dev/tty1
-echo >&${con} "220 Hello"
-
-# This script uses the (shared) home directory as "dictonary" for
-# synchronizing the username and the uid between hosts.
-#
-# Every user has a directory with his username. The directory is
-# owned by root to prevent changes of access rights by the user.
-# The uid and gid of the directory are equal. Thus the name of the
-# directory and the id from the group ownership also provide the
-# association between the username and the uid.
-
-# Add the user with name $1 to the host's "user database". This
-# may not be invoked concurrently.
-createUser() {
- local missing=$1
- local uid
- local userHome="/home/$missing"
- local createOpts=""
-
- # Retrieve or create the uid for the username
- if [ -d "$userHome" ]; then
- # If a home directory exists, use the id from the group ownership as uid
- uid=$(ls -ldn "$userHome" | head -n 1 | awk '{print $4}')
- createOpts="--no-create-home"
- else
- # Else get the maximum of all ids from the group ownership +1
- uid=$(ls -ln "/home" | tail -n +2 | awk '{print $4}' | sort | tail -1)
- uid=$(( $uid + 1 ))
- if [ $uid -lt 1100 ]; then
- uid=1100
- fi
- createOpts="--create-home"
- fi
- groupadd -g $uid $missing
- useradd $missing -u $uid -g $uid $createOpts
-}
-
-# Login the user, i.e. create a desktopn for the user.
-doLogin() {
- user=$1
- if [ "$user" = "root" ]; then
- echo >&${con} "504 Won't log in root"
- return
- fi
-
- # Check if this user is already logged in on tty2
- curUser=$(loginctl -j | jq -r '.[] | select(.tty=="tty2") | .user')
- if [ "$curUser" = "$user" ]; then
- echo >&${con} "201 User already logged in"
- return
- fi
-
- # Terminate a running desktop (fail safe)
- attemptLogout
-
- # Check if username is known on this host. If not, create user
- uid=$(id -u ${user} 2>/dev/null)
- if [ $? != 0 ]; then
- ( flock 200
- createUser ${user}
- ) 200>/home/.gen-uid-lock
-
- # This should now work, else something went wrong
- uid=$(id -u ${user} 2>/dev/null)
- if [ $? != 0 ]; then
- echo >&${con} "451 Cannot determine uid"
- return
- fi
- fi
-
- # Configure user as auto login user
- sed -i '/AutomaticLogin/d' /etc/gdm/custom.conf
- sed -i '/\[daemon\]/a AutomaticLoginEnable=true\nAutomaticLogin='$user \
- /etc/gdm/custom.conf
-
- # Activate user
- systemctl restart gdm
- if [ $? -eq 0 ]; then
- echo >&${con} "201 User logged in successfully"
- else
- echo >&${con} "451 $(tr '\n' ' ' <${temperr})"
- fi
-}
-
-# Attempt to log out a user currently using tty1. This is an intermediate
-# operation that can be invoked from other operations
-attemptLogout() {
- sed -i '/AutomaticLogin/d' /etc/gdm/custom.conf
- systemctl stop gdm
- echo >&${con} "102 Desktop stopped"
-}
-
-# Log out any user currently using tty1. This is invoked when executing
-# the logout command and therefore sends back a 2xx return code.
-# Also try to restart gdm, if it is not running.
-doLogout() {
- attemptLogout
- systemctl restart gdm
- echo >&${con} "202 User logged out"
-}
-
-while read line <&${con}; do
- case $line in
- "login "*) IFS=' ' read -ra args <<< "$line"; doLogin ${args[1]};;
- "logout") doLogout;;
- esac
-done
-
-onExit() {
- doLogout
- if [ -n "$temperr" ]; then
- rm -f $temperr
- fi
- echo >&${con} "240 Quit"
-}
-
-trap onExit EXIT
diff --git a/dev-example/vmop-agent/vmop-agent.service b/dev-example/vmop-agent/vmop-agent.service
deleted file mode 100644
index 11c64f2..0000000
--- a/dev-example/vmop-agent/vmop-agent.service
+++ /dev/null
@@ -1,15 +0,0 @@
-[Unit]
-Description=VM-Operator (Guest) Agent
-BindsTo=dev-virtio\x2dports-org.jdrupes.vmop_agent.0.device
-After=dev-virtio\x2dports-org.jdrupes.vmop_agent.0.device multi-user.target
-IgnoreOnIsolate=True
-
-[Service]
-UMask=0077
-#EnvironmentFile=/etc/sysconfig/vmop-agent
-ExecStart=/usr/local/libexec/vmop-agent
-Restart=always
-RestartSec=0
-
-[Install]
-WantedBy=dev-virtio\x2dports-org.jdrupes.vmop_agent.0.device
diff --git a/gradle.properties b/gradle.properties
deleted file mode 100644
index f97ebb7..0000000
--- a/gradle.properties
+++ /dev/null
@@ -1 +0,0 @@
-org.gradle.parallel=true
diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar
index e644113..ccebba7 100644
Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index a441313..8707e8b 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,7 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-all.zip
networkTimeout=10000
-validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
diff --git a/gradlew b/gradlew
index b740cf1..79a61d4 100755
--- a/gradlew
+++ b/gradlew
@@ -55,7 +55,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
-# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
@@ -83,8 +83,10 @@ done
# This is normally unused
# shellcheck disable=SC2034
APP_BASE_NAME=${0##*/}
-# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
-APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
+APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD=maximum
@@ -131,13 +133,10 @@ location of your Java installation."
fi
else
JAVACMD=java
- if ! command -v java >/dev/null 2>&1
- then
- die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
- fi
fi
# Increase the maximum file descriptors if we can.
@@ -145,7 +144,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
case $MAX_FD in #(
max*)
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
- # shellcheck disable=SC2039,SC3045
+ # shellcheck disable=SC3045
MAX_FD=$( ulimit -H -n ) ||
warn "Could not query maximum file descriptor limit"
esac
@@ -153,7 +152,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
'' | soft) :;; #(
*)
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
- # shellcheck disable=SC2039,SC3045
+ # shellcheck disable=SC3045
ulimit -n "$MAX_FD" ||
warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
@@ -198,15 +197,11 @@ if "$cygwin" || "$msys" ; then
done
fi
-
-# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
-DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
-
-# Collect all arguments for the java command:
-# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
-# and any embedded shellness will be escaped.
-# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
-# treated as '${Hostname}' itself on the command line.
+# Collect all arguments for the java command;
+# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
+# shell script including quotes and variable substitutions, so put them in
+# double quotes to make sure that they get re-expanded; and
+# * put everything else in single quotes, so that it's not re-expanded.
set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
diff --git a/gradlew.bat b/gradlew.bat
index 25da30d..93e3f59 100644
--- a/gradlew.bat
+++ b/gradlew.bat
@@ -43,11 +43,11 @@ set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if %ERRORLEVEL% equ 0 goto execute
-echo. 1>&2
-echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
-echo. 1>&2
-echo Please set the JAVA_HOME variable in your environment to match the 1>&2
-echo location of your Java installation. 1>&2
+echo.
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
goto fail
@@ -57,11 +57,11 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
-echo. 1>&2
-echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
-echo. 1>&2
-echo Please set the JAVA_HOME variable in your environment to match the 1>&2
-echo location of your Java installation. 1>&2
+echo.
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
+echo.
+echo Please set the JAVA_HOME variable in your environment to match the
+echo location of your Java installation.
goto fail
diff --git a/misc/DejaVuSans-Bold.woff2 b/misc/DejaVuSans-Bold.woff2
new file mode 100644
index 0000000..373095f
Binary files /dev/null and b/misc/DejaVuSans-Bold.woff2 differ
diff --git a/misc/DejaVuSans.woff2 b/misc/DejaVuSans.woff2
new file mode 100644
index 0000000..8437d4e
Binary files /dev/null and b/misc/DejaVuSans.woff2 differ
diff --git a/misc/DejaVuSansMono-Bold.woff2 b/misc/DejaVuSansMono-Bold.woff2
new file mode 100644
index 0000000..f2b469a
Binary files /dev/null and b/misc/DejaVuSansMono-Bold.woff2 differ
diff --git a/misc/DejaVuSansMono.woff2 b/misc/DejaVuSansMono.woff2
new file mode 100644
index 0000000..cf200e1
Binary files /dev/null and b/misc/DejaVuSansMono.woff2 differ
diff --git a/misc/DejaVuSerif-Bold.woff2 b/misc/DejaVuSerif-Bold.woff2
new file mode 100644
index 0000000..655ac56
Binary files /dev/null and b/misc/DejaVuSerif-Bold.woff2 differ
diff --git a/misc/DejaVuSerif.woff2 b/misc/DejaVuSerif.woff2
new file mode 100644
index 0000000..238566d
Binary files /dev/null and b/misc/DejaVuSerif.woff2 differ
diff --git a/misc/javadoc-overwrites.css b/misc/javadoc-overwrites.css
deleted file mode 100644
index 7eed81f..0000000
--- a/misc/javadoc-overwrites.css
+++ /dev/null
@@ -1,2 +0,0 @@
-:root { --body-font-size: 16px;}
-:root { --code-font-size: 16px;}
diff --git a/misc/javadoc.bottom.txt b/misc/javadoc.bottom.txt
index d5589ac..bf7dd56 100644
--- a/misc/javadoc.bottom.txt
+++ b/misc/javadoc.bottom.txt
@@ -4,33 +4,26 @@
Terms
— Privacy
-
-
-