From fb73a177484bc2b04625148e367217352ff88d55 Mon Sep 17 00:00:00 2001 From: "Michael N. Lipp" Date: Wed, 5 Mar 2025 15:38:08 +0100 Subject: [PATCH 1/9] Fix link. --- webpages/upgrading.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webpages/upgrading.md b/webpages/upgrading.md index c1331e5..12ff096 100644 --- a/webpages/upgrading.md +++ b/webpages/upgrading.md @@ -10,7 +10,7 @@ layout: vm-operator ## To version 4.0.0 * The VmViewer conlet has been renamed to VmAccess. This affects the - [configuration](https://jdrupes.org/vm-operator/user-gui.html). + [configuration](https://vm-operator.jdrupes.org/user-gui.html). Configuration information using the old path `/Manager/GuiHttpServer/ConsoleWeblet/WebConsole/ComponentCollector/VmViewer` is still accepted for backward compatibility until the next major version, From 5ae162445cb201c052b423fd84f2a25183237345 Mon Sep 17 00:00:00 2001 From: "Michael N. Lipp" Date: Wed, 5 Mar 2025 18:10:54 +0100 Subject: [PATCH 2/9] Add number format. --- dev-example/gen-pool-vm-crds | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-example/gen-pool-vm-crds b/dev-example/gen-pool-vm-crds index 264e3ba..f9cf692 100755 --- a/dev-example/gen-pool-vm-crds +++ b/dev-example/gen-pool-vm-crds @@ -41,7 +41,7 @@ for number in $(seq 1 $count); do if [ -z "$prefix" ]; then prefix=$(basename $template .tpl.yaml) fi - name="$prefix$number" + name="$prefix$(printf %03d $number)" index=$(($number - 1)) esh -o $destination/$name.yaml $template number=$number index=$index done From 7dc68b5ac75e7c0fa0ed9dd9e3a07ff0783a27ce Mon Sep 17 00:00:00 2001 From: "Michael N. Lipp" Date: Wed, 5 Mar 2025 23:24:03 +0100 Subject: [PATCH 3/9] Add documentation. --- webpages/ConfigAccess-preview.png | Bin 0 -> 10855 bytes webpages/PoolAccess-preview.png | Bin 0 -> 7090 bytes webpages/_layouts/vm-operator.html | 5 + webpages/auto-login.md | 84 +++++++++++++++++ webpages/pools.md | 145 ++++++++++++++++++----------- webpages/user-gui.md | 2 +- 6 files changed, 179 insertions(+), 57 deletions(-) create mode 100644 webpages/ConfigAccess-preview.png create mode 100644 webpages/PoolAccess-preview.png create mode 100644 webpages/auto-login.md diff --git a/webpages/ConfigAccess-preview.png b/webpages/ConfigAccess-preview.png new file mode 100644 index 0000000000000000000000000000000000000000..e7523f91b927b6095c8e9e0084730288337eaed5 GIT binary patch literal 10855 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 W8+=P6Gk1XXL7-|ncd>UY|M(w2iYRLU literal 0 HcmV?d00001 diff --git a/webpages/PoolAccess-preview.png b/webpages/PoolAccess-preview.png new file mode 100644 index 0000000000000000000000000000000000000000..34db8cd3cbbfef15c8ce24c00527d48b449e81f2 GIT binary patch literal 7090 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 g-Ks3x9Js;X)W|k&Q(e*m7u|4_

For Admins

  • For Users

  • +

    Advanced

    +

    Upgrading

    Javadoc

    diff --git a/webpages/auto-login.md b/webpages/auto-login.md new file mode 100644 index 0000000..8893bc5 --- /dev/null +++ b/webpages/auto-login.md @@ -0,0 +1,84 @@ +--- +title: "VM-Operator: Auto login — Login users automatically on the guest" +layout: vm-operator +--- + +# Auto Login + +*Since 4.0.0* + +When a user logs in on the web GUI, he has already authenticated with the +VM-Operator. Depending on the environment, it may be tedious to log in again +on the guest. The VM-Operator therefore supports automatic login on the guest +operating system which can streamline the user experience by eliminating +the need for multiple logins. This requires, however, some support from +the guest OS. + +## Prepare the VM + +Automatic login requires an agent in the guest OS. Similar to QEMU's +standard guest agent, the VM-Operator agent communicates with the host +through a tty device (`/dev/virtio-ports/org.jdrupes.vmop_agent.0`). On a modern +Linux system, the device is detected by `udev` which triggers the start +of a systemd service. + +Sample configuration files can be found +[here](https://github.com/mnlipp/VM-Operator/tree/main/dev-example/vmop-agent). +Copy + + * `99-vmop-agent.rules` to `/usr/local/lib/udev/rules.d/99-vmop-agent.rules`, + * `vmop-agent` to `/usr/local/libexec/vmop-agent` and + * `vmop-agent.service` to `/usr/local/lib/systemd/system/vmop-agent.service`. + +Note that some of the target directories do not exist by default and have to +be created first. Don't forget to run `restorecon` on systems with SELinux. + +Enable everything: + +```console +# systemctl daemon-reload +# systemctl enable vmop-agent +# udevadm control --reload-rules +# udevadm trigger + ``` + +## The VM operator agent + +Communication with the VM-Operator agent follows the pattern established +by protocols such as SMTP and FTP. The agent must handle the commands +"`login `" and "`logout`". In response to these commands, the agent +sends back lines that start with a three digit number. The first digit +determines the type of message: "1" for informational, "2" for success +"4" and "5" for errors. The second digit provides information about the +category that the response relates to. The third digit is specific to +the command. + +While this describes the general pattern, the only response code that +the runner evaluates are: + +| Code | Meaning | +| ---- | ------- | +| 220 | Sent by the agent on startup | +| 201 | Login command executed successfully | +| 202 | Logout command executed successfully | + +The sample script is written for the gnome desktop environment. It assumes +that gdm is running as a service by default. On receiving the login command, +it stops gdm and starts a gnome-session for the given user. On receiving the +logout command, it terminates the session and starts gdm again. + +No attempt has been made to make the script configurable. There are too +many possible options. The script should therefore be considered as a +starting point that you can adapt to your needs. + +The sample script also creates new user accounts if a user does not exist +yet. The idea behind this is further explained in the +[section about pools](pools.html#vm-pools). + +## Enable auto login for a VM + +To enable auto login for a VM, specify the user to be logged in in the VM's +definition with "`spec.vm.display.loggedInUser: user-name`". If everything has been +set up correctly, you should be able to open the console and observe the +change from gdm's login screen to the user's desktop when updating the +VM's spec. diff --git a/webpages/pools.md b/webpages/pools.md index 6b1e75f..5b587ea 100644 --- a/webpages/pools.md +++ b/webpages/pools.md @@ -7,67 +7,100 @@ layout: vm-operator *Since 4.0.0* -## Prepare the VM +Not all VMs are replacements for carefully maintained individual PCs. +In many workplaces, a standard configuration can be used where +user-specific data is kept in each user's home directory on a shared +file system. In such cases, an alternative to providing individual +PCs is to offer a pool of VMs and allocate them from the pool to users +as needed. + +## Pool definitions + +The VM-operator supports this use case with a CRD for pools. + +```yaml +apiVersion: "vmoperator.jdrupes.org/v1" +kind: VmPool +metadata: + namespace: vmop-dev + name: test-vms +spec: + retention: "PT4h" + loginOnAssignment: true + permissions: + - user: admin + may: + - accessConsole + - start + - role: user + may: + - accessConsole + - start +``` + +The `retention` specifies how long the assignment of a VM from the pool to +a user is retained after the user closes the console. This allows a user +to interrupt his work for this period of time without risking that +another user takes over the VM. The time is specified as +[ISO 8601 duration](https://en.wikipedia.org/wiki/ISO_8601#Durations). + +Setting `loginOnAssignment` to `true` triggers automatic login of the +user (as described in [section auto login](auto-login.html)) when +the VM is assigned. The `permissions` property defines what a user can +do with a VM assigned to him. + +VMs become members of one (or more) pools by adding the pool name to +property `spec.pools` (an array of strings), e.g.: + +```yaml +apiVersion: "vmoperator.jdrupes.org/v1" +kind: VirtualMachine + +spec: + pools: + - test-vms +``` + +## Accessing a VM from the pool + +Users can access a VM from a pool using the widget described in +[user view](user-gui.html). The widget must be configured to +provide access to a pool instead of to a specific VM. + +![VM Access configuration](ConfigAccess-preview.png){: width="500"} + +Assignment happens when the "start" icon is pushed. If the assigned VM +is not running, it will also be started. The assigned VM's name is +shown in the widget above the action icons. + +![VM Access via pool](PoolAccess-preview.png) + +Apart from showing the assigned VM, the widget behaves in the same way +as it does when configured to access a specific VM. + +## Requirements on the guest + +Some provisions must be made on the guest to ensure that VMs from +pools work as expected. ### Shared file system Mount a shared file system as home file system on all VMs in the pool. -If you want to use the sample script for logging in a user, the filesystem -must support POSIX file access control lists (ACLs). +When using the +[sample agent](https://github.com/mnlipp/VM-Operator/tree/main/dev-example/vmop-agent), +the filesystem must support POSIX file access control lists (ACLs). -### Restrict access +### User management -The VMs should only be accessible via a desktop started by the VM-Operator. +All VMs in the pool must map a given user name to the same user +id. This is typically accomplished by using a central user management, +such as LDAP. The drawback of such a solution is that it is rather +complicated to configure. - * Disable the display manager. +As an alternative, the sample auto login agent provides a very simple +approach that uses the shared home directory for managing the user ids. +Simplified, the script searches for a home directory with the given user +name and derives the user id from it. It then checks if the user id is +known by the guest operating system. If not, the user is added. - ```console - # systemctl disable gdm - # systemctl stop gdm - ``` - - * Disable `getty` on tty1. - - ```console - # systemctl mask getty@tty1 - # systemctl stop getty@tty1 - ``` - -You can, of course, disable `getty` completely. If you do this, make sure -that you can still access your master VM through `ssh`, else you have -locked yourself out. - -Strictly speaking, it is not necessary to disable these services, because -the sample script includes a `Conflicts=` directive in the systemd service -that starts the desktop for the user. However, this is mainly intended for -development purposes and not for production. - -The following should actually be configured for any VM. - - * Prevent suspend/hibernate, because it will lock the VM. - - ```console - # systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target - ``` - -### Install the VM-Operator agent - -The VM-Operator agent runs as a systemd service. Sample configuration -files can be found -[here](https://github.com/mnlipp/VM-Operator/tree/main/dev-example/vmop-agent). -Copy - - * `99-vmop-agent.rules` to `/usr/local/lib/udev/rules.d/99-vmop-agent.rules`, - * `vmop-agent` to `/usr/local/libexec/vmop-agent` and - * `vmop-agent.service` to `/usr/local/lib/systemd/system/vmop-agent.service`. - -Note that some of the target directories do not exist by default and have to -be created first. Don't forget to run `restorecon` on systems with SELinux. - -Enable everything: - -```console -# udevadm control --reload-rules -# systemctl enable vmop-agent -# udevadm trigger - ``` +Details can be found in the comments of the sample script. diff --git a/webpages/user-gui.md b/webpages/user-gui.md index 828eb98..be7b6a2 100644 --- a/webpages/user-gui.md +++ b/webpages/user-gui.md @@ -15,7 +15,7 @@ The idea of the user view is to provide an intuitive widget that allows the users to access their own VMs and to optionally start and stop them. -![VM-Viewer](VmAccess-preview.png) +![VM Access](VmAccess-preview.png) The configuration options resulting from this seemingly simple requirement are unexpectedly complex. From 12c72b3f52e70629faa080f7b6682dedbe323228 Mon Sep 17 00:00:00 2001 From: "Michael N. Lipp" Date: Thu, 6 Mar 2025 09:16:05 +0100 Subject: [PATCH 4/9] Update link. --- overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/overview.md b/overview.md index 30d595e..e263b6a 100644 --- a/overview.md +++ b/overview.md @@ -7,4 +7,4 @@ 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. +See the project's [home page](https://vm-operator.jdrupes.org/) for details. From c51da8650af2ab75b38ee67232ad558dbfb426e1 Mon Sep 17 00:00:00 2001 From: "Michael N. Lipp" Date: Thu, 6 Mar 2025 11:43:32 +0100 Subject: [PATCH 5/9] Editorial changes. --- webpages/auto-login.md | 75 ++++++++++++++++++++++-------------------- webpages/pools.md | 47 ++++++++++++++------------ 2 files changed, 65 insertions(+), 57 deletions(-) diff --git a/webpages/auto-login.md b/webpages/auto-login.md index 8893bc5..c4b859d 100644 --- a/webpages/auto-login.md +++ b/webpages/auto-login.md @@ -7,33 +7,34 @@ layout: vm-operator *Since 4.0.0* -When a user logs in on the web GUI, he has already authenticated with the -VM-Operator. Depending on the environment, it may be tedious to log in again -on the guest. The VM-Operator therefore supports automatic login on the guest -operating system which can streamline the user experience by eliminating -the need for multiple logins. This requires, however, some support from -the guest OS. +When users log into the web GUI, they have already authenticated with the +VM-Operator. In some environments, requiring an additional login on the +guest OS can be cumbersome. To enhance the user experience, the VM-Operator +supports automatic login on the guest operating system, thus eliminating +the need for multiple logins. However, this feature requires specific +support from the guest OS. ## Prepare the VM -Automatic login requires an agent in the guest OS. Similar to QEMU's -standard guest agent, the VM-Operator agent communicates with the host -through a tty device (`/dev/virtio-ports/org.jdrupes.vmop_agent.0`). On a modern -Linux system, the device is detected by `udev` which triggers the start -of a systemd service. +Automatic login requires an agent running inside the guest OS. Similar +to QEMU's standard guest agent, the VM-Operator agent communicates with +the host via a tty device (`/dev/virtio-ports/org.jdrupes.vmop_agent.0`). On +modern Linux systems, `udev` can detect this device and trigger the start +of an associated systemd service. -Sample configuration files can be found +Sample configuration files for a VM-Operator agent are available [here](https://github.com/mnlipp/VM-Operator/tree/main/dev-example/vmop-agent). Copy - * `99-vmop-agent.rules` to `/usr/local/lib/udev/rules.d/99-vmop-agent.rules`, - * `vmop-agent` to `/usr/local/libexec/vmop-agent` and - * `vmop-agent.service` to `/usr/local/lib/systemd/system/vmop-agent.service`. + * `99-vmop-agent.rules` → `/usr/local/lib/udev/rules.d/99-vmop-agent.rules`, + * `vmop-agent` → `/usr/local/libexec/vmop-agent` and + * `vmop-agent.service` → `/usr/local/lib/systemd/system/vmop-agent.service`. -Note that some of the target directories do not exist by default and have to -be created first. Don't forget to run `restorecon` on systems with SELinux. +Some of these target directories may not exist by default and must be +created manually. If your system uses SELinux, run `restorecon` to apply +the correct security contexts. -Enable everything: +Enable the agent: ```console # systemctl daemon-reload @@ -44,17 +45,17 @@ Enable everything: ## The VM operator agent -Communication with the VM-Operator agent follows the pattern established -by protocols such as SMTP and FTP. The agent must handle the commands -"`login `" and "`logout`". In response to these commands, the agent -sends back lines that start with a three digit number. The first digit -determines the type of message: "1" for informational, "2" for success -"4" and "5" for errors. The second digit provides information about the -category that the response relates to. The third digit is specific to -the command. +Communication with the VM-Operator agent follows the pattern established by +protocols such as SMTP and FTP. The agent must handle the commands +"`login `" and "`logout`" on its input. In response to +these commands, the agent sends back lines that start with a three +digit number. The first digit determines the type of message: "1" for +informational, "2" for success and "4" or "5" for errors. The second +digit provides information about the category that a response relates +to. The third digit is specific to the command. -While this describes the general pattern, the only response code that -the runner evaluates are: +While this describes the general pattern, the [runner](runner.html) +only evaluates the following codes: | Code | Meaning | | ---- | ------- | @@ -62,17 +63,19 @@ the runner evaluates are: | 201 | Login command executed successfully | | 202 | Logout command executed successfully | -The sample script is written for the gnome desktop environment. It assumes -that gdm is running as a service by default. On receiving the login command, -it stops gdm and starts a gnome-session for the given user. On receiving the -logout command, it terminates the session and starts gdm again. +The provided sample script is written for the gnome desktop environment. +It assumes that GDM is running as a service by default. When the agent +receives a login command, it stops GDM and starts a gnome-session for +the specified user. Upon receiving the logout command, it terminates +the session and starts GDM again. No attempt has been made to make the script configurable. There are too many possible options. The script should therefore be considered as a -starting point that you can adapt to your needs. +starting point that you may need to adapt to your specific needs. -The sample script also creates new user accounts if a user does not exist -yet. The idea behind this is further explained in the +In addition to starting the desktop for the logged in user, the sample +script automatically creates user accounts if they do not already exist. +The idea behind this behavior is further explained in the [section about pools](pools.html#vm-pools). ## Enable auto login for a VM @@ -80,5 +83,5 @@ yet. The idea behind this is further explained in the To enable auto login for a VM, specify the user to be logged in in the VM's definition with "`spec.vm.display.loggedInUser: user-name`". If everything has been set up correctly, you should be able to open the console and observe the -change from gdm's login screen to the user's desktop when updating the +transition from GDM's login screen to the user's desktop when updating the VM's spec. diff --git a/webpages/pools.md b/webpages/pools.md index 5b587ea..b36397e 100644 --- a/webpages/pools.md +++ b/webpages/pools.md @@ -7,12 +7,17 @@ layout: vm-operator *Since 4.0.0* -Not all VMs are replacements for carefully maintained individual PCs. -In many workplaces, a standard configuration can be used where -user-specific data is kept in each user's home directory on a shared -file system. In such cases, an alternative to providing individual -PCs is to offer a pool of VMs and allocate them from the pool to users -as needed. +Not all VMs are defined as replacements for carefully maintained +individual PCs. In many workplaces, a standardardized VM configuration +can be used where all user-specific data is stored in each user's home +directory. By using a shared file system for home directories, users +can login on any VM and find themselves in their personal +environment. + +If only a subset of users require access simultaneously, this makes it +possible to define a pool of standardardized VMs and dynamically assign +them to users as needed, eliminating the need to define a dedicated VM +for each user. ## Pool definitions @@ -39,18 +44,18 @@ spec: ``` The `retention` specifies how long the assignment of a VM from the pool to -a user is retained after the user closes the console. This allows a user -to interrupt his work for this period of time without risking that -another user takes over the VM. The time is specified as +a user remains valid after the user closes the console. This ensures that +a user can resume work within this timeframe without the risk of another +user taking over the VM. The time is specified as [ISO 8601 duration](https://en.wikipedia.org/wiki/ISO_8601#Durations). Setting `loginOnAssignment` to `true` triggers automatic login of the user (as described in [section auto login](auto-login.html)) when -the VM is assigned. The `permissions` property defines what a user can -do with a VM assigned to him. +the VM is assigned. The `permissions` property specifies the actions +that users or roles can perform on assigned VMs. VMs become members of one (or more) pools by adding the pool name to -property `spec.pools` (an array of strings), e.g.: +the `spec.pools` array, as shown below: ```yaml apiVersion: "vmoperator.jdrupes.org/v1" @@ -69,26 +74,26 @@ provide access to a pool instead of to a specific VM. ![VM Access configuration](ConfigAccess-preview.png){: width="500"} -Assignment happens when the "start" icon is pushed. If the assigned VM -is not running, it will also be started. The assigned VM's name is -shown in the widget above the action icons. +Assignment happens when the "Start" icon is clicked. If the assigned VM +is not already running, it will be started automatically. The assigned +VM's name apears in the widget above the action icons. ![VM Access via pool](PoolAccess-preview.png) Apart from showing the assigned VM, the widget behaves in the same way -as it does when configured to access a specific VM. +as when configured for accessing a specific VM. -## Requirements on the guest +## Guest OS Requirements -Some provisions must be made on the guest to ensure that VMs from -pools work as expected. +To ensure proper functionality when using VM pools, certain requirements +must be met on the guest OS. ### Shared file system -Mount a shared file system as home file system on all VMs in the pool. +All VMs in the pool must mount a shared file system as the home directory. When using the [sample agent](https://github.com/mnlipp/VM-Operator/tree/main/dev-example/vmop-agent), -the filesystem must support POSIX file access control lists (ACLs). +the file system must support POSIX file access control lists (ACLs). ### User management From 1a8412d7670cfe9d76797fb340df0e8d0700aa13 Mon Sep 17 00:00:00 2001 From: "Michael N. Lipp" Date: Thu, 6 Mar 2025 12:59:06 +0100 Subject: [PATCH 6/9] Fix deepCopy for arrays. Isn't used in project. --- .../org/jdrupes/vmoperator/util/DataPath.java | 10 ++++++---- .../jdrupes/vmoperator/util/DataPathTests.java | 17 +++++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 org.jdrupes.vmoperator.util/test/org/jdrupes/vmoperator/util/DataPathTests.java diff --git a/org.jdrupes.vmoperator.util/src/org/jdrupes/vmoperator/util/DataPath.java b/org.jdrupes.vmoperator.util/src/org/jdrupes/vmoperator/util/DataPath.java index 7a6596b..445d383 100644 --- a/org.jdrupes.vmoperator.util/src/org/jdrupes/vmoperator/util/DataPath.java +++ b/org.jdrupes.vmoperator.util/src/org/jdrupes/vmoperator/util/DataPath.java @@ -18,6 +18,7 @@ package org.jdrupes.vmoperator.util; +import java.lang.reflect.Array; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; @@ -157,11 +158,12 @@ public final class DataPath { return (T) copy; } if (object.getClass().isArray()) { - var copy = new ArrayList<>(); - for (var item : (Object[]) object) { - copy.add(deepCopy(item)); + var copy = Array.newInstance(object.getClass().getComponentType(), + Array.getLength(object)); + for (int i = 0; i < Array.getLength(object); i++) { + Array.set(copy, i, deepCopy(Array.get(object, i))); } - return (T) copy.toArray(); + return (T) copy; } if (object instanceof Cloneable) { try { diff --git a/org.jdrupes.vmoperator.util/test/org/jdrupes/vmoperator/util/DataPathTests.java b/org.jdrupes.vmoperator.util/test/org/jdrupes/vmoperator/util/DataPathTests.java new file mode 100644 index 0000000..9c7855f --- /dev/null +++ b/org.jdrupes.vmoperator.util/test/org/jdrupes/vmoperator/util/DataPathTests.java @@ -0,0 +1,17 @@ +package org.jdrupes.vmoperator.util; + +import static org.junit.jupiter.api.Assertions.*; +import org.junit.jupiter.api.Test; + +class DataPathTests { + + @Test + void testArray() { + int[] orig + = { Integer.valueOf(1), Integer.valueOf(2), Integer.valueOf(3) }; + var copy = DataPath.deepCopy(orig); + for (int i = 0; i < orig.length; i++) { + assertEquals(orig[i], copy[i]); + } + } +} From c5a00acf3d401e217cdc4ebe5389e286bd9c1011 Mon Sep 17 00:00:00 2001 From: "Michael N. Lipp" Date: Thu, 6 Mar 2025 13:02:53 +0100 Subject: [PATCH 7/9] "Fix" PMD warning. --- .../src/org/jdrupes/vmoperator/runner/qemu/Runner.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/Runner.java b/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/Runner.java index a01618d..01c4127 100644 --- a/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/Runner.java +++ b/org.jdrupes.vmoperator.runner.qemu/src/org/jdrupes/vmoperator/runner/qemu/Runner.java @@ -192,7 +192,7 @@ import org.jgrapes.util.events.WatchFile; */ @SuppressWarnings({ "PMD.ExcessiveImports", "PMD.AvoidPrintStackTrace", "PMD.DataflowAnomalyAnalysis", "PMD.TooManyMethods", - "PMD.CouplingBetweenObjects" }) + "PMD.CouplingBetweenObjects", "PMD.TooManyFields" }) public class Runner extends Component { private static final String QEMU = "qemu"; From 9459c367aca18b796f471f6043399339b2098afb Mon Sep 17 00:00:00 2001 From: "Michael N. Lipp" Date: Thu, 6 Mar 2025 13:03:04 +0100 Subject: [PATCH 8/9] PMD is wrong. --- .../src/org/jdrupes/vmoperator/common/K8sDynamicModelsBase.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.jdrupes.vmoperator.common/src/org/jdrupes/vmoperator/common/K8sDynamicModelsBase.java b/org.jdrupes.vmoperator.common/src/org/jdrupes/vmoperator/common/K8sDynamicModelsBase.java index 4e21c0e..1813621 100644 --- a/org.jdrupes.vmoperator.common/src/org/jdrupes/vmoperator/common/K8sDynamicModelsBase.java +++ b/org.jdrupes.vmoperator.common/src/org/jdrupes/vmoperator/common/K8sDynamicModelsBase.java @@ -62,7 +62,7 @@ public class K8sDynamicModelsBase } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException exc) { - throw new IllegalArgumentException(exc); + throw new IllegalArgumentException(exc); // NOPMD } } } From f3907ffae9535ee65e14f61ecb7a578e3edcd285 Mon Sep 17 00:00:00 2001 From: "Michael N. Lipp" Date: Thu, 6 Mar 2025 14:40:50 +0100 Subject: [PATCH 9/9] Fix some markdown style issues. --- .markdownlint.yaml | 12 +- package-lock.json | 1003 ++++++++++++++++++++++++++++++++++++++-- package.json | 10 +- webpages/admin-gui.md | 1 - webpages/auto-login.md | 6 +- webpages/index.md | 9 +- webpages/manager.md | 3 +- webpages/pools.md | 2 +- webpages/runner.md | 16 +- webpages/user-gui.md | 3 +- 10 files changed, 997 insertions(+), 68 deletions(-) diff --git a/.markdownlint.yaml b/.markdownlint.yaml index 3501bd3..6ed5002 100644 --- a/.markdownlint.yaml +++ b/.markdownlint.yaml @@ -1,4 +1,4 @@ -# See https://github.com/DavidAnson/markdownlint/blob/main/schema/.markdownlint.yaml +# See [rules](https://github.com/DavidAnson/markdownlint/blob/main/schema/.markdownlint.yaml) # Default state for all rules default: true @@ -27,12 +27,4 @@ MD036: false # MD043/required-headings : Required heading structure : # https://github.com/DavidAnson/markdownlint/blob/v0.37.4/doc/md043.md -MD043: - # List of headings - headings: [ - "# Head", - "## Item", - "### Detail" - ] - # Match case of headings - match_case: false +MD043: false diff --git a/package-lock.json b/package-lock.json index 97aaade..4bfe990 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,9 @@ "requires": true, "packages": { "": { + "dependencies": { + "markdownlint-cli": "^0.44.0" + }, "devDependencies": { "@rollup/plugin-node-resolve": "^15.0.1", "@rollup/plugin-replace": "^5.0.2", @@ -12,6 +15,7 @@ "documentation": "^14.0.1", "install": "^0.13.0", "jsdoc": "^4.0.2", + "markdownlint": "^0.37.4", "node-sass": "^9.0.0", "npm": "^8.11.0", "rollup": "^4.1.5", @@ -1240,7 +1244,6 @@ "version": "4.1.12", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", - "dev": true, "dependencies": { "@types/ms": "*" } @@ -1272,6 +1275,12 @@ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, + "node_modules/@types/katex": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@types/katex/-/katex-0.16.7.tgz", + "integrity": "sha512-HMwFiRujE5PjrgwHQ25+bsLJgowjGjm5Z8FVSf0N6PwgJrwxH0QxzHYDcKsTfV3wva0vzrpqMTJS2jXPr5BMEQ==", + "license": "MIT" + }, "node_modules/@types/linkify-it": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", @@ -1312,8 +1321,7 @@ "node_modules/@types/ms": { "version": "0.7.34", "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", - "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==", - "dev": true + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" }, "node_modules/@types/normalize-package-data": { "version": "2.4.4", @@ -1348,8 +1356,7 @@ "node_modules/@types/unist": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", - "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==", - "dev": true + "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "6.21.0", @@ -1736,8 +1743,7 @@ "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "node_modules/array-union": { "version": "2.1.0", @@ -1779,8 +1785,7 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/binary-extensions": { "version": "2.3.0", @@ -1810,7 +1815,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0" } @@ -2021,7 +2025,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", - "dev": true, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -2041,7 +2044,16 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", - "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "license": "MIT", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -2357,7 +2369,6 @@ "version": "4.3.5", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", - "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -2408,7 +2419,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", - "dev": true, "dependencies": { "character-entities": "^2.0.0" }, @@ -2417,6 +2427,15 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "license": "MIT", + "engines": { + "node": ">=4.0.0" + } + }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -2437,11 +2456,23 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "dev": true, "engines": { "node": ">=6" } }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/diff": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", @@ -2639,7 +2670,6 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "dev": true, "engines": { "node": ">=0.12" }, @@ -3143,8 +3173,7 @@ "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "node_modules/fsevents": { "version": "2.3.3", @@ -3246,7 +3275,6 @@ "version": "9.3.5", "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", - "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "minimatch": "^8.0.2", @@ -3276,7 +3304,6 @@ "version": "8.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", - "dev": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -3291,7 +3318,6 @@ "version": "4.2.8", "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", - "dev": true, "engines": { "node": ">=8" } @@ -3822,6 +3848,30 @@ "node": ">=0.10.0" } }, + "node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "license": "MIT", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", @@ -3890,6 +3940,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -3920,6 +3980,16 @@ "node": ">=0.10.0" } }, + "node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/is-lambda": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", @@ -4048,7 +4118,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, "dependencies": { "argparse": "^2.0.1" }, @@ -4173,10 +4242,10 @@ } }, "node_modules/jsonc-parser": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.1.tgz", - "integrity": "sha512-AilxAyFOAcK5wA1+LeaySVBrHsGQvUFCDWXKpZjzaL0PqW+xfBOttn8GNtWKFWqneyMZj41MWF9Kl6iPWLwgOA==", - "dev": true + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "license": "MIT" }, "node_modules/jsonfile": { "version": "6.1.0", @@ -4190,6 +4259,40 @@ "graceful-fs": "^4.1.6" } }, + "node_modules/jsonpointer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-5.0.1.tgz", + "integrity": "sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/katex": { + "version": "0.16.21", + "resolved": "https://registry.npmjs.org/katex/-/katex-0.16.21.tgz", + "integrity": "sha512-XvqR7FgOHtWupfMiigNzmh+MgUVmDGU2kXZm899ZkPfcuoPuFxyHmXsgATDpFZDAXCI8tvinaVcDo8PIIJSo4A==", + "funding": [ + "https://opencollective.com/katex", + "https://github.com/sponsors/katex" + ], + "license": "MIT", + "dependencies": { + "commander": "^8.3.0" + }, + "bin": { + "katex": "cli.js" + } + }, + "node_modules/katex/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -4270,7 +4373,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", - "dev": true, "dependencies": { "uc.micro": "^2.0.0" } @@ -4450,7 +4552,6 @@ "version": "14.1.0", "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", - "dev": true, "dependencies": { "argparse": "^2.0.1", "entities": "^4.4.0", @@ -4483,6 +4584,559 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/markdownlint": { + "version": "0.37.4", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.37.4.tgz", + "integrity": "sha512-u00joA/syf3VhWh6/ybVFkib5Zpj2e5KB/cfCei8fkSRuums6nyisTWGqjTWIOFoFwuXoTBQQiqlB4qFKp8ncQ==", + "license": "MIT", + "dependencies": { + "markdown-it": "14.1.0", + "micromark": "4.0.1", + "micromark-core-commonmark": "2.0.2", + "micromark-extension-directive": "3.0.2", + "micromark-extension-gfm-autolink-literal": "2.1.0", + "micromark-extension-gfm-footnote": "2.1.0", + "micromark-extension-gfm-table": "2.1.0", + "micromark-extension-math": "3.1.0", + "micromark-util-types": "2.0.1" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/DavidAnson" + } + }, + "node_modules/markdownlint-cli": { + "version": "0.44.0", + "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.44.0.tgz", + "integrity": "sha512-ZJTAONlvF9NkrIBltCdW15DxN9UTbPiKMEqAh2EU2gwIFlrCMavyCEPPO121cqfYOrLUJWW8/XKWongstmmTeQ==", + "license": "MIT", + "dependencies": { + "commander": "~13.1.0", + "glob": "~10.4.5", + "ignore": "~7.0.3", + "js-yaml": "~4.1.0", + "jsonc-parser": "~3.3.1", + "jsonpointer": "~5.0.1", + "markdownlint": "~0.37.4", + "minimatch": "~9.0.5", + "run-con": "~1.3.2", + "smol-toml": "~1.3.1" + }, + "bin": { + "markdownlint": "markdownlint.js" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/markdownlint-cli/node_modules/commander": { + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz", + "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/markdownlint-cli/node_modules/ignore": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.3.tgz", + "integrity": "sha512-bAH5jbK/F3T3Jls4I0SO1hmPR0dKU0a7+SY6n1yzRtG54FLO8d6w/nxLFX2Nb7dBu6cCWXPaAME6cYqFUMmuCA==", + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/markdownlint-cli/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/markdownlint/node_modules/micromark": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-4.0.1.tgz", + "integrity": "sha512-eBPdkcoCNvYcxQOAKAlceo5SNdzZWfF+FcSupREAzdAh9rRmE239CEQAiTwIgblwnoM8zzj35sZ5ZwvSEOF6Kw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-decode-numeric-character-reference": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/markdownlint/node_modules/micromark-core-commonmark": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-2.0.2.tgz", + "integrity": "sha512-FKjQKbxd1cibWMM1P9N+H8TwlgGgSkWZMmfuVucLCHaYqeSvJ0hFeHsIa65pA2nYbes0f8LDHPMrd9X7Ujxg9w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "devlop": "^1.0.0", + "micromark-factory-destination": "^2.0.0", + "micromark-factory-label": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-title": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-html-tag-name": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-subtokenize": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/markdownlint/node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/markdownlint/node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/markdownlint/node_modules/micromark-extension-gfm-table": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.0.tgz", + "integrity": "sha512-Ub2ncQv+fwD70/l4ou27b4YzfNaCJOvyX4HxXU15m7mpYY+rjuWzsLIPZHJL253Z643RpbcP1oeIJlQ/SKW67g==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/markdownlint/node_modules/micromark-factory-destination": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", + "integrity": "sha512-Xe6rDdJlkmbFRExpTOmRj9N3MaWmbAgdpSrBQvCFqhezUn4AHqJHbaEnfbVYYiexVSs//tqOdY/DxhjdCiJnIA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/markdownlint/node_modules/micromark-factory-label": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-2.0.1.tgz", + "integrity": "sha512-VFMekyQExqIW7xIChcXn4ok29YE3rnuyveW3wZQWWqF4Nv9Wk5rgJ99KzPvHjkmPXF93FXIbBp6YdW3t71/7Vg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/markdownlint/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/markdownlint/node_modules/micromark-factory-title": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-2.0.1.tgz", + "integrity": "sha512-5bZ+3CjhAd9eChYTHsjy6TGxpOFSKgKKJPJxr293jTbfry2KDoWkhBb6TcPVB4NmzaPhMs1Frm9AZH7OD4Cjzw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/markdownlint/node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/markdownlint/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/markdownlint/node_modules/micromark-util-chunked": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-2.0.1.tgz", + "integrity": "sha512-QUNFEOPELfmvv+4xiNg2sRYeS/P84pTW0TCgP5zc9FpXetHY0ab7SxKyAQCNCc1eK0459uoLI1y5oO5Vc1dbhA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/markdownlint/node_modules/micromark-util-classify-character": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-2.0.1.tgz", + "integrity": "sha512-K0kHzM6afW/MbeWYWLjoHQv1sgg2Q9EccHEDzSkxiP/EaagNzCm7T/WMKZ3rjMbvIpvBiZgwR3dKMygtA4mG1Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/markdownlint/node_modules/micromark-util-combine-extensions": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-2.0.1.tgz", + "integrity": "sha512-OnAnH8Ujmy59JcyZw8JSbK9cGpdVY44NKgSM7E9Eh7DiLS2E9RNQf0dONaGDzEG9yjEl5hcqeIsj4hfRkLH/Bg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-chunked": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/markdownlint/node_modules/micromark-util-decode-numeric-character-reference": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-2.0.2.tgz", + "integrity": "sha512-ccUbYk6CwVdkmCQMyr64dXz42EfHGkPQlBj5p7YVGzq8I7CtjXZJrubAYezf7Rp+bjPseiROqe7G6foFd+lEuw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/markdownlint/node_modules/micromark-util-encode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-2.0.1.tgz", + "integrity": "sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/markdownlint/node_modules/micromark-util-html-tag-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-2.0.1.tgz", + "integrity": "sha512-2cNEiYDhCWKI+Gs9T0Tiysk136SnR13hhO8yW6BGNyhOC4qYFnwF1nKfD3HFAIXA5c45RrIG1ub11GiXeYd1xA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/markdownlint/node_modules/micromark-util-normalize-identifier": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-2.0.1.tgz", + "integrity": "sha512-sxPqmo70LyARJs0w2UclACPUUEqltCkJ6PhKdMIDuJ3gSf/Q+/GIe3WKl0Ijb/GyH9lOpUkRAO2wp0GVkLvS9Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/markdownlint/node_modules/micromark-util-resolve-all": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-2.0.1.tgz", + "integrity": "sha512-VdQyxFWFT2/FGJgwQnJYbe1jjQoNTS4RjglmSjTUlpUMa95Htx9NHeYW4rGDJzbjvCsl9eLjMQwGeElsqmzcHg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/markdownlint/node_modules/micromark-util-sanitize-uri": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-2.0.1.tgz", + "integrity": "sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-encode": "^2.0.0", + "micromark-util-symbol": "^2.0.0" + } + }, + "node_modules/markdownlint/node_modules/micromark-util-subtokenize": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-2.1.0.tgz", + "integrity": "sha512-XQLu552iSctvnEcgXw6+Sx75GflAPNED1qx7eBJ+wydBb2KCbRZe+NwvIEEMM83uml1+2WSXpBAcp9IUCgCYWA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/markdownlint/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/markdownlint/node_modules/micromark-util-types": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.1.tgz", + "integrity": "sha512-534m2WhVTddrcKVepwmVEVnUAmtrx9bfIjNoQHRqfnvdaHQiFytEhJoTgpWJvDEXCO5gLTQh3wYC1PgOJA4NSQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, "node_modules/marked": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/marked/-/marked-4.3.0.tgz", @@ -4802,8 +5456,7 @@ "node_modules/mdurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", - "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", - "dev": true + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==" }, "node_modules/meow": { "version": "9.0.0", @@ -5038,6 +5691,119 @@ "uvu": "^0.5.0" } }, + "node_modules/micromark-extension-directive": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/micromark-extension-directive/-/micromark-extension-directive-3.0.2.tgz", + "integrity": "sha512-wjcXHgk+PPdmvR58Le9d7zQYWy+vKEU9Se44p2CrCDPiLr2FMyiT4Fyb5UFKFC66wGB3kPlgD7q3TnoqPS7SZA==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-factory-whitespace": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0", + "parse-entities": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-directive/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-directive/node_modules/micromark-factory-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-2.0.1.tgz", + "integrity": "sha512-Ob0nuZ3PKt/n0hORHyvoD9uZhr+Za8sFoP+OnMcnWK5lngSzALgQYKMr9RJVOWLqQYuyn6ulqGWSXdwf6F80lQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-directive/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-directive/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-directive/node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, "node_modules/micromark-extension-gfm": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-2.0.3.tgz", @@ -5159,6 +5925,97 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/micromark-extension-math": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-math/-/micromark-extension-math-3.1.0.tgz", + "integrity": "sha512-lvEqd+fHjATVs+2v/8kg9i5Q0AP2k85H0WUOwpIVvUML8BapsMvh1XAogmQjOCsLpoKRCVQqEkQBB3NhVBcsOg==", + "license": "MIT", + "dependencies": { + "@types/katex": "^0.16.0", + "devlop": "^1.0.0", + "katex": "^0.16.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-math/node_modules/micromark-factory-space": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-2.0.1.tgz", + "integrity": "sha512-zRkxjtBxxLd2Sc0d+fbnEunsTj46SWXgXciZmHq0kDYGnck/ZSGj9/wULTV95uoeYiK5hRXP2mJ98Uo4cq/LQg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-math/node_modules/micromark-util-character": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-2.1.1.tgz", + "integrity": "sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT", + "dependencies": { + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + } + }, + "node_modules/micromark-extension-math/node_modules/micromark-util-symbol": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-2.0.1.tgz", + "integrity": "sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, + "node_modules/micromark-extension-math/node_modules/micromark-util-types": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-2.0.2.tgz", + "integrity": "sha512-Yw0ECSpJoViF1qTU4DC6NwtC4aWGt1EkzaQB8KPPyCRR8z9TWeV0HbEFGTO+ZY1wB22zmxnJqhPyTpOVCpeHTA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "license": "MIT" + }, "node_modules/micromark-factory-destination": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz", @@ -5569,6 +6426,15 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/minimist-options": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", @@ -5709,8 +6575,7 @@ "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/nan": { "version": "2.20.0", @@ -8897,6 +9762,25 @@ "node": ">=6" } }, + "node_modules/parse-entities": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", + "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", + "license": "MIT", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/parse-filepath": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", @@ -9002,7 +9886,6 @@ "version": "1.11.1", "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, "dependencies": { "lru-cache": "^10.2.0", "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" @@ -9018,7 +9901,6 @@ "version": "10.2.2", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", - "dev": true, "engines": { "node": "14 || >=16.14" } @@ -9027,7 +9909,6 @@ "version": "7.1.2", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, "engines": { "node": ">=16 || 14 >=14.17" } @@ -9777,7 +10658,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", - "dev": true, "engines": { "node": ">=6" } @@ -10354,6 +11234,42 @@ "integrity": "sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w==", "dev": true }, + "node_modules/run-con": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/run-con/-/run-con-1.3.2.tgz", + "integrity": "sha512-CcfE+mYiTcKEzg0IqS08+efdnH0oJ3zV0wSUFBNrMHMuxCtXvBCLzCJHatwuXDcu/RlhjTziTo/a1ruQik6/Yg==", + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~4.1.0", + "minimist": "^1.2.8", + "strip-json-comments": "~3.1.1" + }, + "bin": { + "run-con": "cli.js" + } + }, + "node_modules/run-con/node_modules/ini": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz", + "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==", + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/run-con/node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -10567,6 +11483,18 @@ "integrity": "sha512-g6T+p7QO8npa+/hNx9ohv1E5pVCmWrVCUzUXJyLdMmftX6ER0oiWY/w9knEonLpnOp6b6FenKnMfR8gqwWdwig==", "dev": true }, + "node_modules/smol-toml": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.3.1.tgz", + "integrity": "sha512-tEYNll18pPKHroYSmLLrksq233j021G0giwW7P3D24jC54pQ5W5BXMsQ/Mvw1OJCmEYDgY+lrzT+3nNUtoNfXQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 18" + }, + "funding": { + "url": "https://github.com/sponsors/cyyynthia" + } + }, "node_modules/socks": { "version": "2.8.3", "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", @@ -11102,8 +12030,7 @@ "node_modules/uc.micro": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", - "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", - "dev": true + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==" }, "node_modules/unc-path-regex": { "version": "0.1.2", diff --git a/package.json b/package.json index 329bcd5..1f72d6f 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "documentation": "^14.0.1", "install": "^0.13.0", "jsdoc": "^4.0.2", + "markdownlint": "^0.37.4", "node-sass": "^9.0.0", "npm": "^8.11.0", "rollup": "^4.1.5", @@ -22,8 +23,8 @@ "typescript": "^5.2.2" }, "overrides": { - "node-gyp": "^10.1.0", - "glob": "^9.0.0" + "node-gyp": "^10.1.0", + "glob": "^9.0.0" }, "eslintConfig": { "root": true, @@ -34,5 +35,8 @@ }, "eslintIgnore": [ "node_modules/**" - ] + ], + "dependencies": { + "markdownlint-cli": "^0.44.0" + } } diff --git a/webpages/admin-gui.md b/webpages/admin-gui.md index 4b7f5b2..b968a74 100644 --- a/webpages/admin-gui.md +++ b/webpages/admin-gui.md @@ -19,4 +19,3 @@ the VMs and adjust the CPU and RAM usages (modifies the definition in kubernetes). ![VM-Operator GUI](VM-Operator-GUI-view.png) - diff --git a/webpages/auto-login.md b/webpages/auto-login.md index c4b859d..59856b2 100644 --- a/webpages/auto-login.md +++ b/webpages/auto-login.md @@ -11,14 +11,14 @@ When users log into the web GUI, they have already authenticated with the VM-Operator. In some environments, requiring an additional login on the guest OS can be cumbersome. To enhance the user experience, the VM-Operator supports automatic login on the guest operating system, thus eliminating -the need for multiple logins. However, this feature requires specific +the need for multiple logins. However, this feature requires specific support from the guest OS. ## Prepare the VM Automatic login requires an agent running inside the guest OS. Similar to QEMU's standard guest agent, the VM-Operator agent communicates with -the host via a tty device (`/dev/virtio-ports/org.jdrupes.vmop_agent.0`). On +the host via a tty device (`/dev/virtio-ports/org.jdrupes.vmop_agent.0`). On modern Linux systems, `udev` can detect this device and trigger the start of an associated systemd service. @@ -30,7 +30,7 @@ Copy * `vmop-agent` → `/usr/local/libexec/vmop-agent` and * `vmop-agent.service` → `/usr/local/lib/systemd/system/vmop-agent.service`. -Some of these target directories may not exist by default and must be +Some of these target directories may not exist by default and must be created manually. If your system uses SELinux, run `restorecon` to apply the correct security contexts. diff --git a/webpages/index.md b/webpages/index.md index ea9c5eb..9ad3aba 100644 --- a/webpages/index.md +++ b/webpages/index.md @@ -27,6 +27,7 @@ If you just want to try out things, you can skip the remainder of this page and proceed to "[the manager](manager.html)". ## Motivation + The project was triggered by a remark in the discussion about RedHat [dropping SPICE support](https://bugzilla.redhat.com/show_bug.cgi?id=2030592) from the RHEL packages. Which means that you have to run Qemu in a @@ -55,9 +56,11 @@ close to simply deploying the pod (you get the restart and some PVC management "for free"). A second look, however, reveals that Kubernetes has more to offer. -* It has a well defined API for managing resources. -* It provides access to different kinds of managed storage for the VMs. -* Its managing features *are* useful for running the component that + + * It has a well defined API for managing resources. + * It provides access to different kinds of managed storage for the VMs. + * Its managing features *are* useful for running the component that + manages the pods with the VMs. And if you use Kubernetes anyway, well then the VMs within Kubernetes diff --git a/webpages/manager.md b/webpages/manager.md index d283484..8748ad8 100644 --- a/webpages/manager.md +++ b/webpages/manager.md @@ -40,7 +40,8 @@ default files for creating these resources using the default namespace can be found in the [deploy](https://github.com/mnlipp/VM-Operator/tree/main/deploy) directory. I recommend to use -[kustomize](https://kubernetes.io/docs/tasks/manage-kubernetes-objects/kustomization/) to create your own configuration. +[kustomize](https://kubernetes.io/docs/tasks/manage-kubernetes-objects/kustomization/) +to create your own configuration. ## Initial Configuration diff --git a/webpages/pools.md b/webpages/pools.md index b36397e..41e26ef 100644 --- a/webpages/pools.md +++ b/webpages/pools.md @@ -76,7 +76,7 @@ provide access to a pool instead of to a specific VM. Assignment happens when the "Start" icon is clicked. If the assigned VM is not already running, it will be started automatically. The assigned -VM's name apears in the widget above the action icons. +VM's name apears in the widget above the action icons. ![VM Access via pool](PoolAccess-preview.png) diff --git a/webpages/runner.md b/webpages/runner.md index a6a744d..a877b57 100644 --- a/webpages/runner.md +++ b/webpages/runner.md @@ -44,9 +44,9 @@ A sample configuration file with annotated options can be found As the runner implementation uses the [JGrapes](https://jgrapes.org/) framework, the file follows the framework's -[conventions](https://jgrapes.org/latest-release/javadoc/org/jgrapes/util/YamlConfigurationStore.html). The top level "`/Runner`" selects -the component to be configured. Nested within is the information -to be applied to the component. +[conventions](https://jgrapes.org/latest-release/javadoc/org/jgrapes/util/YamlConfigurationStore.html). +The top level "`/Runner`" selects the component to be configured. Nested +within is the information to be applied to the component. The main entries in the configuration file are the "template" and the "vm" information. The runner processes the @@ -58,8 +58,8 @@ defines a particular VM type, i.e. it contains the "nasty details" that do not need to be modified for some given set of VM instances. The templates provided with the runner can be found -[here](https://github.com/mnlipp/VM-Operator/tree/main/org.jdrupes.vmoperator.runner.qemu/templates). When details -of the VM configuration need modification, a new VM type +[here](https://github.com/mnlipp/VM-Operator/tree/main/org.jdrupes.vmoperator.runner.qemu/templates). +When details of the VM configuration need modification, a new VM type (i.e. a new template) has to be defined. Authoring a new template requires some knowledge about the [qemu invocation](https://www.qemu.org/docs/master/system/invocation.html). @@ -92,7 +92,8 @@ which may be used in a stand-alone development configuration. The runner supports adaption to changes of the RAM size (using the balloon device) and to changes of the number of CPUs. Note that in order to get new CPUs online on Linux guests, you need a -[udev rule](https://docs.kernel.org/core-api/cpu_hotplug.html#user-space-notification) which is not installed by default[^simplest]. +[udev rule](https://docs.kernel.org/core-api/cpu_hotplug.html#user-space-notification) +which is not installed by default[^simplest]. The runner also changes the images loaded in CDROM drives. If the drive is locked, i.e. if it doesn't respond to the "open tray" command @@ -101,7 +102,8 @@ the change will be suspended until the VM opens the tray. Finally, `powerdownTimeout` can be changed while the qemu process runs. [^simplest]: The simplest form of the rule is probably: - ``` + + ```txt ACTION=="add", SUBSYSTEM=="cpu", ATTR{online}="1" ``` diff --git a/webpages/user-gui.md b/webpages/user-gui.md index be7b6a2..3ff816f 100644 --- a/webpages/user-gui.md +++ b/webpages/user-gui.md @@ -77,7 +77,8 @@ objects that either specify a role or a user. ## Console access Access to the VM's console is implemented by generating a -[connection file](https://manpages.debian.org/testing/virt-viewer/remote-viewer.1.en.html#CONNECTION_FILE) for virt-viewer when the user clicks on +[connection file](https://manpages.debian.org/testing/virt-viewer/remote-viewer.1.en.html#CONNECTION_FILE) +for virt-viewer when the user clicks on the console icon. If automatic open is enabled for this kind of files in the browser, the console opens without further user action.