From a66ab34b15ce9fd15d7f440d4c6c0e0b945e55d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roger=20Westerb=C3=B8?= Date: Sat, 13 Dec 2025 21:24:25 +0100 Subject: [PATCH 1/5] How to setup vitistack And updating npm packages --- README.md | 3 + docs/howtoguide/install-kubevirt.md | 40 ++ docs/howtoguide/setup-vitistack.md | 213 ++++++ docs/images/vitistack-setup.excalidraw.png | Bin 0 -> 97764 bytes docs/reference/api/ipam-api.md | 6 +- mkdocs.yml | 2 + package-lock.json | 794 ++++++++++----------- package.json | 8 +- 8 files changed, 643 insertions(+), 423 deletions(-) create mode 100644 docs/howtoguide/install-kubevirt.md create mode 100644 docs/howtoguide/setup-vitistack.md create mode 100644 docs/images/vitistack-setup.excalidraw.png diff --git a/README.md b/README.md index 08007b4..65487ec 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,9 @@ npm install # Serve locally mkdocs serve +# or with live reload +mkdocs serve --livereload + # Build for production mkdocs build ``` diff --git a/docs/howtoguide/install-kubevirt.md b/docs/howtoguide/install-kubevirt.md new file mode 100644 index 0000000..2e17c4d --- /dev/null +++ b/docs/howtoguide/install-kubevirt.md @@ -0,0 +1,40 @@ +# Kubevirt + +## Install kubevirt +(docs with kind: https://kubevirt.io/quickstart_kind) +```bash +export VERSION=$(curl -s https://storage.googleapis.com/kubevirt-prow/release/kubevirt/kubevirt/stable.txt) + +echo $VERSION +kubectl create -f "https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/kubevirt-operator.yaml" +``` + +## Virtualized environment +If running in a virtualized environment + +If the kind cluster runs on a virtual machine consider enabling nested virtualization. Follow the instructions described here. If for any reason nested virtualization cannot be enabled do enable KubeVirt emulation as follows: + +```bash +kubectl -n kubevirt patch kubevirt kubevirt --type=merge --patch '{"spec":{"configuration":{"developerConfiguration":{"useEmulation":true}}}}' +``` + +## Deploy the KubeVirt custom resource definitions + +```bash +kubectl create -f "https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/kubevirt-cr.yaml" +``` + + +## Virtctl +KubeVirt provides an additional binary called virtctl for quick access to the serial and graphical ports of a VM and also handle start/stop operations. + +Install +virtctl can be retrieved from the release page of the KubeVirt github page. + +```bash +VERSION=$(kubectl get kubevirt.kubevirt.io/kubevirt -n kubevirt -o=jsonpath="{.status.observedKubeVirtVersion}") +ARCH=$(uname -s | tr A-Z a-z)-$(uname -m | sed 's/x86_64/amd64/') || windows-amd64.exe +echo ${ARCH} +curl -L -o virtctl https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/virtctl-${VERSION}-${ARCH} +sudo install -m 0755 virtctl /usr/local/bin +``` \ No newline at end of file diff --git a/docs/howtoguide/setup-vitistack.md b/docs/howtoguide/setup-vitistack.md new file mode 100644 index 0000000..612b717 --- /dev/null +++ b/docs/howtoguide/setup-vitistack.md @@ -0,0 +1,213 @@ +# How to setup vitistack + +## Prerequisites +First of all you need a Kubernetes cluster to run all the Vitistack operators. + +### On prem +Create hardware nodes an install ex Talos, K0s or other kubernetes solutions + +### Cloud +- Azure Kubernetes Service (AKS) +- Elastic Kubernetes Service (EKS) +- Scaleway +- Upcloud +- or others + +### Locally +You could use Kind (https://kind.sigs.k8s.io/docs/user/quick-start/#installation) or Talosctl (https://docs.siderolabs.com/talos/v1.11/getting-started/talosctl) to install spin up a Kubernetes cluster locally. + + +## Visual cluster overview + +![Vitistack cluster setup](../images/vitistack-setup.excalidraw.png "Vitistack cluster setup") + +It is also possible that the supervisor cluster also has Kubevirt installed, so there is also support for only one cluster. But it is wise to spread out the risk onto multiple clusters, incause of errors. + +## Install Vitistack CRDS + +Using Helm (recommended) + +First, login to GitHub Container Registry + +Username: your GitHub username + +Password: a Personal Access Token (PAT) with `read:packages` scope + +Create a PAT at: https://github.com/settings/tokens/new?scopes=read:packages + +```bash +helm registry login ghcr.io +helm install vitistack-crds oci://ghcr.io/vitistack/crds +``` + +Or using kubectl (no authentication required) + +```bash +kubectl apply -f https://github.com/vitistack/common/releases/latest/download/crds.yaml +``` + +## Machine classes +These a example machine classes + +### Small +filename: machineclass-small.yaml +```yaml +apiVersion: vitistack.io/v1alpha1 +kind: MachineClass +metadata: + name: small +spec: + displayName: Small + description: Small instance with 2 cores and 8Gi memory + enabled: true + default: false + category: Standard + cpu: + cores: 2 + sockets: 1 + threads: 1 + memory: + quantity: 8Gi + machineProviders: [] +``` + +```bash +kubectl apply -f machineclass-small.yaml +``` + +### Medium +filename: machineclass-medium.yaml +```yaml +apiVersion: vitistack.io/v1alpha1 +kind: MachineClass +metadata: + name: medium +spec: + displayName: Medium + description: Medium instance with 4 cores and 16Gi memory + enabled: true + default: true + category: Standard + cpu: + cores: 4 + sockets: 1 + threads: 1 + memory: + quantity: 16Gi + machineProviders: [] + +``` + +```bash +kubectl apply -f machineclass-medium.yaml +``` + +### Large +filename: machineclass-large.yaml +```yaml +apiVersion: vitistack.io/v1alpha1 +kind: MachineClass +metadata: + name: large +spec: + displayName: Large + description: Large instance with 4 cores and 32Gi memory + enabled: true + default: false + category: Standard + cpu: + cores: 4 + sockets: 1 + threads: 1 + memory: + quantity: 32Gi + machineProviders: [] +``` + +```bash +kubectl apply -f machineclass-large.yaml +``` + +## Kea Operator +To be continued + +## Vitistack operator + +The vitistack operator handles the vitistack crd object. The operator fetches information and adds it to the vitistack crd object, so other solutions could show or integrate with the vitistack. One example is ROR (Release Operate Report) found here: https://github.com/norskHelsenett/ror + +Install the vitistack operator by: + +```bash +helm install vitistack-operator oci://ghcr.io/vitistack/helm/vitistack-operator +``` + +## Kubevirt +To create machines with kubevirt we need to install kubevirt into a own cluster (or into the supervisor cluster) + +### To install kubevirt +[Guide to install Kubevirt](install-kubevirt.md) + +### Verify kubevirt components + +```bash +kubectl get kubevirt.kubevirt.io/kubevirt -n kubevirt -o=jsonpath="{.status.phase}" +``` + +Check the components +```bash +kubectl get all -n kubevirtkubectl get all -n kubevirt +``` + +### How create a KubeVirtConfig + +Create a k8s secret from file content (kubeconfig file to the kubevirt cluster) + +```bash +kubectl create secret generic kubevirt-provider --from-file=kubeconfig=` +``` + +### Create the KubevirtConfig + +Create and modify this yaml + +Filename: kubevirtconfig.yaml +```yaml +apiVersion: vitistack.io/v1alpha1 +kind: KubevirtConfig +metadata: + name: kubevirt-provider +spec: + name: kubevirt-provider + secretNamespace: default + kubeconfigSecretRef: kubevirt-provider +``` + +And then: + +`kubectl apply -f kubevirtconfig.yaml` + + +### Install the Kubevirt-operator + +```bash +helm registry login ghcr.io +helm install viti-kubevirt-operator oci://ghcr.io/vitistack/helm/kubevirt-operator +``` + +## Proxmox-operator + +You need one or more Proxmox instances. + +To install proxmox, follow this installation guide: +- https://proxmox.com/en/products/proxmox-virtual-environment/get-started +- https://pve.proxmox.com/pve-docs/chapter-pve-installation.html + +### Install the Proxmox operator + +```bash +helm registry login ghcr.io +helm install viti-proxmox-operator oci://ghcr.io/vitistack/helm/proxmox-operator +``` + +## Talos Operator +To be continued \ No newline at end of file diff --git a/docs/images/vitistack-setup.excalidraw.png b/docs/images/vitistack-setup.excalidraw.png new file mode 100644 index 0000000000000000000000000000000000000000..5549c34f917c3909873ff377bab2821777025ed4 GIT binary patch literal 97764 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
$}o#in9-VS9Ak9 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" } }, "node_modules/@axe-core/cli": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/@axe-core/cli/-/cli-4.10.1.tgz", - "integrity": "sha512-Lz7Fg1FG5f39xq6MvPBgVuggzPfCkpkcc1D0Mh3fkprhrWn/YICY+htfQ3LV1Q8BXG2kbt6uh/VmdGXTf/YEpQ==", + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/@axe-core/cli/-/cli-4.11.0.tgz", + "integrity": "sha512-FBzR/+m63FXWMnbrDm2iMccvsWd56wsUB6wk/AUy0Qr9TXF5GXCRDO6KPeymJ8cgsMHBTL5bjFVVXGWhRyTJEQ==", "dev": true, "license": "MPL-2.0", "dependencies": { - "@axe-core/webdriverjs": "^4.10.1", - "axe-core": "~4.10.2", + "@axe-core/webdriverjs": "^4.11.0", + "axe-core": "~4.11.0", "chromedriver": "latest", "colors": "^1.4.0", "commander": "^9.4.1", - "dotenv": "^16.4.5", - "selenium-webdriver": "~4.22.0" + "dotenv": "^17.2.2", + "selenium-webdriver": "~4.35.0" }, "bin": { "axe": "dist/src/bin/cli.js" @@ -41,13 +41,13 @@ } }, "node_modules/@axe-core/webdriverjs": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/@axe-core/webdriverjs/-/webdriverjs-4.10.1.tgz", - "integrity": "sha512-XGNB5WGqLU87t9xSeB0tZyYWzYksn/wCHeDAsOkdEarsYzkY7834OpBSiUqXOE6GByILsnX1uyR7UFfIAtHdjg==", + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/@axe-core/webdriverjs/-/webdriverjs-4.11.0.tgz", + "integrity": "sha512-Qt9DWcCQIPU9TMfCQnibFn0JDuvoSzfGs4nZM7LJeae/i3bpZ5qqLjc94U09BUneYQjTicfwHlKTcr9mmAb2cg==", "dev": true, "license": "MPL-2.0", "dependencies": { - "axe-core": "~4.10.2" + "axe-core": "~4.11.0" }, "peerDependencies": { "selenium-webdriver": ">3.0.0-beta || >=2.53.1 || >4.0.0-alpha" @@ -69,24 +69,31 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", - "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" } }, + "node_modules/@bazel/runfiles": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@bazel/runfiles/-/runfiles-6.5.0.tgz", + "integrity": "sha512-RzahvqTkfpY2jsDxo8YItPX+/iZ6hbiikw1YhE0bA9EKBR5Og8Pa6FHn9PO9M0zaXRVsr0GFQLKbB/0rzy9SzA==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/@formatjs/ecma402-abstract": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.3.4.tgz", - "integrity": "sha512-qrycXDeaORzIqNhBOx0btnhpD1c+/qFIHAN9znofuMJX6QBwtbrmlpWfD4oiUUD2vJUOIYFA/gYtg2KAMGG7sA==", + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/@formatjs/ecma402-abstract/-/ecma402-abstract-2.3.6.tgz", + "integrity": "sha512-HJnTFeRM2kVFVr5gr5kH1XP6K0JcJtE7Lzvtr3FS/so5f1kpsqqqxy5JF+FRaO6H2qmcMfAUIox7AJteieRtVw==", "dev": true, "license": "MIT", "dependencies": { "@formatjs/fast-memoize": "2.2.7", - "@formatjs/intl-localematcher": "0.6.1", + "@formatjs/intl-localematcher": "0.6.2", "decimal.js": "^10.4.3", "tslib": "^2.8.0" } @@ -116,14 +123,14 @@ "license": "0BSD" }, "node_modules/@formatjs/icu-messageformat-parser": { - "version": "2.11.2", - "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.11.2.tgz", - "integrity": "sha512-AfiMi5NOSo2TQImsYAg8UYddsNJ/vUEv/HaNqiFjnI3ZFfWihUtD5QtuX6kHl8+H+d3qvnE/3HZrfzgdWpsLNA==", + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.11.4.tgz", + "integrity": "sha512-7kR78cRrPNB4fjGFZg3Rmj5aah8rQj9KPzuLsmcSn4ipLXQvC04keycTI1F7kJYDwIXtT2+7IDEto842CfZBtw==", "dev": true, "license": "MIT", "dependencies": { - "@formatjs/ecma402-abstract": "2.3.4", - "@formatjs/icu-skeleton-parser": "1.8.14", + "@formatjs/ecma402-abstract": "2.3.6", + "@formatjs/icu-skeleton-parser": "1.8.16", "tslib": "^2.8.0" } }, @@ -135,13 +142,13 @@ "license": "0BSD" }, "node_modules/@formatjs/icu-skeleton-parser": { - "version": "1.8.14", - "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.14.tgz", - "integrity": "sha512-i4q4V4qslThK4Ig8SxyD76cp3+QJ3sAqr7f6q9VVfeGtxG9OhiAk3y9XF6Q41OymsKzsGQ6OQQoJNY4/lI8TcQ==", + "version": "1.8.16", + "resolved": "https://registry.npmjs.org/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.8.16.tgz", + "integrity": "sha512-H13E9Xl+PxBd8D5/6TVUluSpxGNvFSlN/b3coUp0e0JpuWXXnQDiavIpY3NnvSp4xhEMoXyyBvVfdFX8jglOHQ==", "dev": true, "license": "MIT", "dependencies": { - "@formatjs/ecma402-abstract": "2.3.4", + "@formatjs/ecma402-abstract": "2.3.6", "tslib": "^2.8.0" } }, @@ -153,9 +160,9 @@ "license": "0BSD" }, "node_modules/@formatjs/intl-localematcher": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.6.1.tgz", - "integrity": "sha512-ePEgLgVCqi2BBFnTMWPfIghu6FkbZnnBVhO2sSxvLfrdFw7wCHAHiDoM2h4NRgjbaY7+B7HgOLZGkK187pZTZg==", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/@formatjs/intl-localematcher/-/intl-localematcher-0.6.2.tgz", + "integrity": "sha512-XOMO2Hupl0wdd172Y06h6kLpBz6Dv+J4okPLl4LPtzbr8f66WbIoy4ev98EBuZ6ZK4h5ydTN6XneT4QVpD7cdA==", "dev": true, "license": "MIT", "dependencies": { @@ -242,20 +249,20 @@ } }, "node_modules/@lhci/cli": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@lhci/cli/-/cli-0.14.0.tgz", - "integrity": "sha512-TxOH9pFBnmmN7Jmo2Aimxx5UhE8veqXpHfFJDMWsCVxkwh7mGxcAWchGl84mK139SZbbRmerqZ72c+h2nG9/QQ==", + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/@lhci/cli/-/cli-0.15.1.tgz", + "integrity": "sha512-yhC0oXnXqGHYy1xl4D8YqaydMZ/khFAnXGY/o2m/J3PqPa/D0nj3V6TLoH02oVMFeEF2AQim7UbmdXMiXx2tOw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@lhci/utils": "0.14.0", + "@lhci/utils": "0.15.1", "chrome-launcher": "^0.13.4", "compression": "^1.7.4", "debug": "^4.3.1", "express": "^4.17.1", "inquirer": "^6.3.1", "isomorphic-fetch": "^3.0.0", - "lighthouse": "12.1.0", + "lighthouse": "12.6.1", "lighthouse-logger": "1.2.0", "open": "^7.1.0", "proxy-agent": "^6.4.0", @@ -269,25 +276,29 @@ } }, "node_modules/@lhci/utils": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@lhci/utils/-/utils-0.14.0.tgz", - "integrity": "sha512-LyP1RbvYQ9xNl7uLnl5AO8fDRata9MG/KYfVFKFkYenlsVS6QJsNjLzWNEoMIaE4jOPdQQlSp4tO7dtnyDxzbQ==", + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/@lhci/utils/-/utils-0.15.1.tgz", + "integrity": "sha512-WclJnUQJeOMY271JSuaOjCv/aA0pgvuHZS29NFNdIeI14id8eiFsjith85EGKYhljgoQhJ2SiW4PsVfFiakNNw==", "dev": true, "license": "Apache-2.0", "dependencies": { "debug": "^4.3.1", "isomorphic-fetch": "^3.0.0", "js-yaml": "^3.13.1", - "lighthouse": "12.1.0", + "lighthouse": "12.6.1", "tree-kill": "^1.2.1" } }, "node_modules/@paulirish/trace_engine": { - "version": "0.0.23", - "resolved": "https://registry.npmjs.org/@paulirish/trace_engine/-/trace_engine-0.0.23.tgz", - "integrity": "sha512-2ym/q7HhC5K+akXkNV6Gip3oaHpbI6TsGjmcAsl7bcJ528MVbacPQeoauLFEeLXH4ulJvsxQwNDIg/kAEhFZxw==", + "version": "0.0.53", + "resolved": "https://registry.npmjs.org/@paulirish/trace_engine/-/trace_engine-0.0.53.tgz", + "integrity": "sha512-PUl/vlfo08Oj804VI5nDPeSk9vyslnBlVzDDwFt8SUVxY8+KdGMkra/vrXjEEHe8gb7+RqVTfOIlGw0nyrEelA==", "dev": true, - "license": "BSD-3-Clause" + "license": "BSD-3-Clause", + "dependencies": { + "legacy-javascript": "latest", + "third-party-web": "latest" + } }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", @@ -301,19 +312,18 @@ } }, "node_modules/@puppeteer/browsers": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.3.0.tgz", - "integrity": "sha512-ioXoq9gPxkss4MYhD+SFaU9p1IHFUX0ILAWFPyjGaBdjLsYAlZw6j1iLA0N/m12uVHLFDfSYNF7EQccjinIMDA==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.11.0.tgz", + "integrity": "sha512-n6oQX6mYkG8TRPuPXmbPidkUbsSRalhmaaVAQxvH1IkQy63cwsH+kOjB3e4cpCDHg0aSvsiX9bQ4s2VB6mGWUQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "debug": "^4.3.5", + "debug": "^4.4.3", "extract-zip": "^2.0.1", "progress": "^2.0.3", - "proxy-agent": "^6.4.0", - "semver": "^7.6.3", - "tar-fs": "^3.0.6", - "unbzip2-stream": "^1.4.3", + "proxy-agent": "^6.5.0", + "semver": "^7.7.3", + "tar-fs": "^3.1.1", "yargs": "^17.7.2" }, "bin": { @@ -395,9 +405,9 @@ } }, "node_modules/@puppeteer/browsers/node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", "dev": true, "license": "ISC", "bin": { @@ -492,105 +502,89 @@ "node": ">=12" } }, - "node_modules/@sentry/core": { - "version": "6.19.7", - "resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.19.7.tgz", - "integrity": "sha512-tOfZ/umqB2AcHPGbIrsFLcvApdTm9ggpi/kQZFkej7kMphjT+SGBiQfYtjyg9jcRW+ilAR4JXC9BGKsdEQ+8Vw==", + "node_modules/@sentry-internal/tracing": { + "version": "7.120.4", + "resolved": "https://registry.npmjs.org/@sentry-internal/tracing/-/tracing-7.120.4.tgz", + "integrity": "sha512-Fz5+4XCg3akeoFK+K7g+d7HqGMjmnLoY2eJlpONJmaeT9pXY7yfUyXKZMmMajdE2LxxKJgQ2YKvSCaGVamTjHw==", "dev": true, - "license": "BSD-3-Clause", + "license": "MIT", "dependencies": { - "@sentry/hub": "6.19.7", - "@sentry/minimal": "6.19.7", - "@sentry/types": "6.19.7", - "@sentry/utils": "6.19.7", - "tslib": "^1.9.3" + "@sentry/core": "7.120.4", + "@sentry/types": "7.120.4", + "@sentry/utils": "7.120.4" }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/@sentry/hub": { - "version": "6.19.7", - "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.19.7.tgz", - "integrity": "sha512-y3OtbYFAqKHCWezF0EGGr5lcyI2KbaXW2Ik7Xp8Mu9TxbSTuwTe4rTntwg8ngPjUQU3SUHzgjqVB8qjiGqFXCA==", + "node_modules/@sentry/core": { + "version": "7.120.4", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.120.4.tgz", + "integrity": "sha512-TXu3Q5kKiq8db9OXGkWyXUbIxMMuttB5vJ031yolOl5T/B69JRyAoKuojLBjRv1XX583gS1rSSoX8YXX7ATFGA==", "dev": true, - "license": "BSD-3-Clause", + "license": "MIT", "dependencies": { - "@sentry/types": "6.19.7", - "@sentry/utils": "6.19.7", - "tslib": "^1.9.3" + "@sentry/types": "7.120.4", + "@sentry/utils": "7.120.4" }, "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/@sentry/minimal": { - "version": "6.19.7", - "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.19.7.tgz", - "integrity": "sha512-wcYmSJOdvk6VAPx8IcmZgN08XTXRwRtB1aOLZm+MVHjIZIhHoBGZJYTVQS/BWjldsamj2cX3YGbGXNunaCfYJQ==", + "node_modules/@sentry/integrations": { + "version": "7.120.4", + "resolved": "https://registry.npmjs.org/@sentry/integrations/-/integrations-7.120.4.tgz", + "integrity": "sha512-kkBTLk053XlhDCg7OkBQTIMF4puqFibeRO3E3YiVc4PGLnocXMaVpOSCkMqAc1k1kZ09UgGi8DxfQhnFEjUkpA==", "dev": true, - "license": "BSD-3-Clause", + "license": "MIT", "dependencies": { - "@sentry/hub": "6.19.7", - "@sentry/types": "6.19.7", - "tslib": "^1.9.3" + "@sentry/core": "7.120.4", + "@sentry/types": "7.120.4", + "@sentry/utils": "7.120.4", + "localforage": "^1.8.1" }, "engines": { - "node": ">=6" + "node": ">=8" } }, "node_modules/@sentry/node": { - "version": "6.19.7", - "resolved": "https://registry.npmjs.org/@sentry/node/-/node-6.19.7.tgz", - "integrity": "sha512-gtmRC4dAXKODMpHXKfrkfvyBL3cI8y64vEi3fDD046uqYcrWdgoQsffuBbxMAizc6Ez1ia+f0Flue6p15Qaltg==", + "version": "7.120.4", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-7.120.4.tgz", + "integrity": "sha512-qq3wZAXXj2SRWhqErnGCSJKUhPSlZ+RGnCZjhfjHpP49KNpcd9YdPTIUsFMgeyjdh6Ew6aVCv23g1hTP0CHpYw==", "dev": true, - "license": "BSD-3-Clause", + "license": "MIT", "dependencies": { - "@sentry/core": "6.19.7", - "@sentry/hub": "6.19.7", - "@sentry/types": "6.19.7", - "@sentry/utils": "6.19.7", - "cookie": "^0.4.1", - "https-proxy-agent": "^5.0.0", - "lru_map": "^0.3.3", - "tslib": "^1.9.3" + "@sentry-internal/tracing": "7.120.4", + "@sentry/core": "7.120.4", + "@sentry/integrations": "7.120.4", + "@sentry/types": "7.120.4", + "@sentry/utils": "7.120.4" }, "engines": { - "node": ">=6" - } - }, - "node_modules/@sentry/node/node_modules/cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.6" + "node": ">=8" } }, "node_modules/@sentry/types": { - "version": "6.19.7", - "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.19.7.tgz", - "integrity": "sha512-jH84pDYE+hHIbVnab3Hr+ZXr1v8QABfhx39KknxqKWr2l0oEItzepV0URvbEhB446lk/S/59230dlUUIBGsXbg==", + "version": "7.120.4", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.120.4.tgz", + "integrity": "sha512-cUq2hSSe6/qrU6oZsEP4InMI5VVdD86aypE+ENrQ6eZEVLTCYm1w6XhW1NvIu3UuWh7gZec4a9J7AFpYxki88Q==", "dev": true, - "license": "BSD-3-Clause", + "license": "MIT", "engines": { - "node": ">=6" + "node": ">=8" } }, "node_modules/@sentry/utils": { - "version": "6.19.7", - "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.19.7.tgz", - "integrity": "sha512-z95ECmE3i9pbWoXQrD/7PgkBAzJYR+iXtPuTkpBjDKs86O3mT+PXOT3BAn79w2wkn7/i3vOGD2xVr1uiMl26dA==", + "version": "7.120.4", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.120.4.tgz", + "integrity": "sha512-zCKpyDIWKHwtervNK2ZlaK8mMV7gVUijAgFeJStH+CU/imcdquizV3pFLlSQYRswG+Lbyd6CT/LGRh3IbtkCFw==", "dev": true, - "license": "BSD-3-Clause", + "license": "MIT", "dependencies": { - "@sentry/types": "6.19.7", - "tslib": "^1.9.3" + "@sentry/types": "7.120.4" }, "engines": { - "node": ">=6" + "node": ">=8" } }, "node_modules/@testim/chrome-version": { @@ -652,19 +646,6 @@ "node": ">= 0.6" } }, - "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, "node_modules/ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", @@ -753,9 +734,9 @@ "license": "MIT" }, "node_modules/axe-core": { - "version": "4.10.3", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.3.tgz", - "integrity": "sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==", + "version": "4.11.0", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.11.0.tgz", + "integrity": "sha512-ilYanEU8vxxBexpJd8cWM4ElSQq4QctCLKih0TSfjIfCQTeyH/6zVrmIJfLPrKTKJRbiG+cfnZbQIjAlJmF1jQ==", "dev": true, "license": "MPL-2.0", "engines": { @@ -775,11 +756,19 @@ } }, "node_modules/b4a": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz", - "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==", + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.7.3.tgz", + "integrity": "sha512-5Q2mfq2WfGuFp3uS//0s6baOJLMoVduPYVeNmDYxu5OUA1/cBfvr2RIS7vi62LdNj/urk1hfmj867I3qt6uZ7Q==", "dev": true, - "license": "Apache-2.0" + "license": "Apache-2.0", + "peerDependencies": { + "react-native-b4a": "*" + }, + "peerDependenciesMeta": { + "react-native-b4a": { + "optional": true + } + } }, "node_modules/balanced-match": { "version": "1.0.2", @@ -789,24 +778,33 @@ "license": "MIT" }, "node_modules/bare-events": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.5.4.tgz", - "integrity": "sha512-+gFfDkR8pj4/TrWCGUGWmJIkBwuxPS5F+a5yWjOHQt2hHvNZd5YLzadjmDUtFmMM4y429bnKLa8bYBMHcYdnQA==", + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.8.2.tgz", + "integrity": "sha512-riJjyv1/mHLIPX4RwiK+oW9/4c3TEUeORHKefKAKnZ5kyslbN+HXowtbaVEqt4IMUB7OXlfixcs6gsFeo/jhiQ==", "dev": true, "license": "Apache-2.0", - "optional": true + "peerDependencies": { + "bare-abort-controller": "*" + }, + "peerDependenciesMeta": { + "bare-abort-controller": { + "optional": true + } + } }, "node_modules/bare-fs": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.1.5.tgz", - "integrity": "sha512-1zccWBMypln0jEE05LzZt+V/8y8AQsQQqxtklqaIyg5nu6OAYFhZxPXinJTSG+kU5qyNmeLgcn9AW7eHiCHVLA==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.5.2.tgz", + "integrity": "sha512-veTnRzkb6aPHOvSKIOy60KzURfBdUflr5VReI+NSaPL6xf+XLdONQgZgpYvUuZLVQ8dCqxpBAudaOM1+KpAUxw==", "dev": true, "license": "Apache-2.0", "optional": true, "dependencies": { "bare-events": "^2.5.4", "bare-path": "^3.0.0", - "bare-stream": "^2.6.4" + "bare-stream": "^2.6.4", + "bare-url": "^2.2.2", + "fast-fifo": "^1.3.2" }, "engines": { "bare": ">=1.16.0" @@ -821,9 +819,9 @@ } }, "node_modules/bare-os": { - "version": "3.6.1", - "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.1.tgz", - "integrity": "sha512-uaIjxokhFidJP+bmmvKSgiMzj2sV5GPHaZVAIktcxcpCyBFFWO+YlikVAdhmUo2vYFvFhOXIAlldqV29L8126g==", + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.6.2.tgz", + "integrity": "sha512-T+V1+1srU2qYNBmJCXZkUY5vQ0B4FSlL3QDROnKQYOqeiQR8UbjNHlPa+TIbM4cuidiN9GaTaOZgSEgsvPbh5A==", "dev": true, "license": "Apache-2.0", "optional": true, @@ -843,9 +841,9 @@ } }, "node_modules/bare-stream": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.6.5.tgz", - "integrity": "sha512-jSmxKJNJmHySi6hC42zlZnq00rga4jjxcgNZjY9N5WlOe/iOoGRtdwGsHzQv2RlH2KOYMwGUXhf2zXd32BA9RA==", + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.7.0.tgz", + "integrity": "sha512-oyXQNicV1y8nc2aKffH+BUHFRXmx6VrPzlnaEvMhram0nPBrKcEdcyBg5r08D0i8VxngHFAiVyn1QKXpSG0B8A==", "dev": true, "license": "Apache-2.0", "optional": true, @@ -865,26 +863,16 @@ } } }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "node_modules/bare-url": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.3.2.tgz", + "integrity": "sha512-ZMq4gd9ngV5aTMa5p9+UfY0b3skwhHELaDkhEHetMdX0LRkW9kzaym4oo/Eh+Ghm0CCDuMTsRIGM/ytUc1ZYmw==", "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "bare-path": "^3.0.0" + } }, "node_modules/basic-ftp": { "version": "5.0.5", @@ -897,13 +885,12 @@ } }, "node_modules/bfj": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/bfj/-/bfj-8.0.0.tgz", - "integrity": "sha512-6KJe4gFrZ4lhmvWcUIj37yFAs36mi2FZXuTkw6udZ/QsX/znFypW4SatqcLA5K5T4BAWgJZD73UFEJJQxuJjoA==", + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/bfj/-/bfj-9.1.2.tgz", + "integrity": "sha512-EetpSUewwznXQ7yRtxHCgE5RLZV718n9cOYXe5BlhYKuNs0UkidHaUOe6Jlgbf+viGTQeg8mYhm5Wr4c2AB3gA==", "dev": true, "license": "MIT", "dependencies": { - "bluebird": "^3.7.2", "check-types": "^11.2.3", "hoopy": "^0.1.4", "jsonpath": "^1.1.1", @@ -913,13 +900,6 @@ "node": ">= 18.0.0" } }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true, - "license": "MIT" - }, "node_modules/body-parser": { "version": "1.20.3", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", @@ -972,31 +952,6 @@ "balanced-match": "^1.0.0" } }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, "node_modules/buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", @@ -1136,15 +1091,14 @@ } }, "node_modules/chromium-bidi": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.6.3.tgz", - "integrity": "sha512-qXlsCmpCZJAnoTYI83Iu6EdYQpMYdVkCfq08KDh2pmlVqK5t5IA9mGs4/LwCwp4fqisSOMXZxP3HIh8w8aRn0A==", + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-11.0.0.tgz", + "integrity": "sha512-cM3DI+OOb89T3wO8cpPSro80Q9eKYJ7hGVXoGS3GkDPxnYSqiv+6xwpIf6XERyJ9Tdsl09hmNmY94BkgZdVekw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "mitt": "3.0.1", - "urlpattern-polyfill": "10.0.0", - "zod": "3.23.8" + "mitt": "^3.0.1", + "zod": "^3.24.1" }, "peerDependencies": { "devtools-protocol": "*" @@ -1487,9 +1441,9 @@ "license": "Python-2.0" }, "node_modules/cosmiconfig/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", "dev": true, "license": "MIT", "dependencies": { @@ -1525,9 +1479,9 @@ } }, "node_modules/csp_evaluator": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/csp_evaluator/-/csp_evaluator-1.1.1.tgz", - "integrity": "sha512-N3ASg0C4kNPUaNxt1XAvzHIVuzdtr8KLgfk1O8WDyimp1GisPAHESupArO2ieHk9QWbrJ/WkQODyh21Ps/xhxw==", + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/csp_evaluator/-/csp_evaluator-1.1.5.tgz", + "integrity": "sha512-EL/iN9etCTzw/fBnp0/uj0f5BOOGvZut2mzsiiBZ/FdT6gFQCKRO/tmcKOxn5drWZ2Ndm/xBb1SI4zwWbGtmIw==", "dev": true, "license": "Apache-2.0" }, @@ -1542,9 +1496,9 @@ } }, "node_modules/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "dev": true, "license": "MIT", "dependencies": { @@ -1570,9 +1524,9 @@ } }, "node_modules/decimal.js": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.5.0.tgz", - "integrity": "sha512-8vDa8Qxvr/+d94hSh5P3IJwI5t8/c0KsMp+g8bNw9cY2icONa5aPfvKeieW1WlG0WQYwwhJ7mjui2xtiePQSXw==", + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.6.0.tgz", + "integrity": "sha512-YpgQiITW3JXGntzdUmyUR1V812Hn8T1YVXhCu+wO3OpS4eU9l4YdD3qjyiKdV6mvV29zapkMeD390UVEf2lkUg==", "dev": true, "license": "MIT" }, @@ -1640,9 +1594,9 @@ } }, "node_modules/devtools-protocol": { - "version": "0.0.1312386", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1312386.tgz", - "integrity": "sha512-DPnhUXvmvKT2dFA/j7B+riVLUt9Q6RKJlcppojL5CoRywJJKLDYnRlw0gTFKfgDPHP5E04UoB71SxoJlVZy8FA==", + "version": "0.0.1467305", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1467305.tgz", + "integrity": "sha512-LxwMLqBoPPGpMdRL4NkLFRNy3QLp6Uqa7GNp1v6JaBheop2QrB9Q7q0A/q/CYYP9sBfZdHOyszVx4gc9zyk7ow==", "dev": true, "license": "BSD-3-Clause" }, @@ -1660,9 +1614,9 @@ } }, "node_modules/dotenv": { - "version": "16.5.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.5.0.tgz", - "integrity": "sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==", + "version": "17.2.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.2.3.tgz", + "integrity": "sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==", "dev": true, "license": "BSD-2-Clause", "engines": { @@ -1776,9 +1730,9 @@ } }, "node_modules/envinfo": { - "version": "7.11.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.11.1.tgz", - "integrity": "sha512-8PiZgZNIB4q/Lw4AhOvAfB/ityHAd2bli3lESSWmWSzSsl5dKpy5N1d1Rfkd2teq/g9xN90lc6o98DOjMeYHpg==", + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.14.0.tgz", + "integrity": "sha512-CO40UI41xDQzhLB1hWyqUKgFhs250pNcGbyGKe1l/e4FSaI/+YE4IMG76GDt0In67WLPACIITC+sOi08x4wIvg==", "dev": true, "license": "MIT", "bin": { @@ -1789,9 +1743,9 @@ } }, "node_modules/error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", + "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1940,6 +1894,16 @@ "node": ">= 0.6" } }, + "node_modules/events-universal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", + "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "bare-events": "^2.7.0" + } + }, "node_modules/express": { "version": "4.21.2", "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", @@ -2481,20 +2445,6 @@ "node": ">= 14" } }, - "node_modules/https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, - "license": "MIT", - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -2508,27 +2458,6 @@ "node": ">=0.10.0" } }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "BSD-3-Clause" - }, "node_modules/image-ssim": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/image-ssim/-/image-ssim-0.2.0.tgz", @@ -2603,15 +2532,15 @@ } }, "node_modules/intl-messageformat": { - "version": "10.7.16", - "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.7.16.tgz", - "integrity": "sha512-UmdmHUmp5CIKKjSoE10la5yfU+AYJAaiYLsodbjL4lji83JNvgOQUjGaGhGrpFCb0Uh7sl7qfP1IyILa8Z40ug==", + "version": "10.7.18", + "resolved": "https://registry.npmjs.org/intl-messageformat/-/intl-messageformat-10.7.18.tgz", + "integrity": "sha512-m3Ofv/X/tV8Y3tHXLohcuVuhWKo7BBq62cqY15etqmLxg2DZ34AGGgQDeR+SCta2+zICb1NX83af0GJmbQ1++g==", "dev": true, "license": "BSD-3-Clause", "dependencies": { - "@formatjs/ecma402-abstract": "2.3.4", + "@formatjs/ecma402-abstract": "2.3.6", "@formatjs/fast-memoize": "2.2.7", - "@formatjs/icu-messageformat-parser": "2.11.2", + "@formatjs/icu-messageformat-parser": "2.11.4", "tslib": "^2.8.0" } }, @@ -2824,9 +2753,9 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "version": "3.14.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.2.tgz", + "integrity": "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==", "dev": true, "license": "MIT", "dependencies": { @@ -2889,6 +2818,16 @@ "setimmediate": "^1.0.5" } }, + "node_modules/jszip/node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "immediate": "~3.0.5" + } + }, "node_modules/kleur": { "version": "4.1.5", "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", @@ -2899,6 +2838,13 @@ "node": ">=6" } }, + "node_modules/legacy-javascript": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/legacy-javascript/-/legacy-javascript-0.0.1.tgz", + "integrity": "sha512-lPyntS4/aS7jpuvOlitZDFifBCb4W8L/3QU0PLbUTUj+zYah8rfVjYic88yG7ZKTxhS5h9iz7duT8oUXKszLhg==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", @@ -2914,9 +2860,9 @@ } }, "node_modules/lie": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", - "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", + "integrity": "sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==", "dev": true, "license": "MIT", "dependencies": { @@ -2924,36 +2870,36 @@ } }, "node_modules/lighthouse": { - "version": "12.1.0", - "resolved": "https://registry.npmjs.org/lighthouse/-/lighthouse-12.1.0.tgz", - "integrity": "sha512-PQLaNcv3tQcybnYux6T8uoS6+RNrNYvVJBbGo0kkbD4XTjesGslOXWeMkUQDK7c28nLfVZi7gYWDUsicTLglKQ==", + "version": "12.6.1", + "resolved": "https://registry.npmjs.org/lighthouse/-/lighthouse-12.6.1.tgz", + "integrity": "sha512-85WDkjcXAVdlFem9Y6SSxqoKiz/89UsDZhLpeLJIsJ4LlHxw047XTZhlFJmjYCB7K5S1erSBAf5cYLcfyNbH3A==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@paulirish/trace_engine": "^0.0.23", - "@sentry/node": "^6.17.4", - "axe-core": "^4.9.1", - "chrome-launcher": "^1.1.2", + "@paulirish/trace_engine": "0.0.53", + "@sentry/node": "^7.0.0", + "axe-core": "^4.10.3", + "chrome-launcher": "^1.2.0", "configstore": "^5.0.1", - "csp_evaluator": "1.1.1", - "devtools-protocol": "0.0.1312386", + "csp_evaluator": "1.1.5", + "devtools-protocol": "0.0.1467305", "enquirer": "^2.3.6", "http-link-header": "^1.1.1", "intl-messageformat": "^10.5.3", "jpeg-js": "^0.4.4", "js-library-detector": "^6.7.0", "lighthouse-logger": "^2.0.1", - "lighthouse-stack-packs": "1.12.1", - "lodash": "^4.17.21", + "lighthouse-stack-packs": "1.12.2", + "lodash-es": "^4.17.21", "lookup-closest-locale": "6.2.0", "metaviewport-parser": "0.3.0", "open": "^8.4.0", "parse-cache-control": "1.0.1", - "puppeteer-core": "^22.11.1", + "puppeteer-core": "^24.10.0", "robots-parser": "^3.0.1", "semver": "^5.3.0", "speedline-core": "^1.4.3", - "third-party-web": "^0.24.3", + "third-party-web": "^0.26.6", "tldts-icann": "^6.1.16", "ws": "^7.0.0", "yargs": "^17.3.1", @@ -2965,7 +2911,7 @@ "smokehouse": "cli/test/smokehouse/frontends/smokehouse-bin.js" }, "engines": { - "node": ">=18.16" + "node": ">=18.20" } }, "node_modules/lighthouse-logger": { @@ -2997,9 +2943,9 @@ "license": "MIT" }, "node_modules/lighthouse-stack-packs": { - "version": "1.12.1", - "resolved": "https://registry.npmjs.org/lighthouse-stack-packs/-/lighthouse-stack-packs-1.12.1.tgz", - "integrity": "sha512-i4jTmg7tvZQFwNFiwB+nCK6a7ICR68Xcwo+VIVd6Spi71vBNFUlds5HiDrSbClZdkQDON2Bhqv+KKJIo5zkPeA==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/lighthouse-stack-packs/-/lighthouse-stack-packs-1.12.2.tgz", + "integrity": "sha512-Ug8feS/A+92TMTCK6yHYLwaFMuelK/hAKRMdldYkMNwv+d9PtWxjXEg6rwKtsUXTADajhdrhXyuNCJ5/sfmPFw==", "dev": true, "license": "Apache-2.0" }, @@ -3030,9 +2976,9 @@ } }, "node_modules/lighthouse/node_modules/chrome-launcher": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-1.2.0.tgz", - "integrity": "sha512-JbuGuBNss258bvGil7FT4HKdC3SC2K7UAEUqiPy3ACS3Yxo3hAW6bvFpCu2HsIJLgTqxgEX6BkujvzZfLpUD0Q==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-1.2.1.tgz", + "integrity": "sha512-qmFR5PLMzHyuNJHwOloHPAHhbaNglkfeV/xDtt5b7xiFFyU1I+AZZX0PYseMuhenJSSirgxELYIbswcoc+5H4A==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -3083,16 +3029,6 @@ "dev": true, "license": "MIT" }, - "node_modules/lighthouse/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "2.0.0" - } - }, "node_modules/lighthouse/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -3117,23 +3053,16 @@ } }, "node_modules/lighthouse/node_modules/lighthouse-logger": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-2.0.1.tgz", - "integrity": "sha512-ioBrW3s2i97noEmnXxmUq7cjIcVRjT5HBpAYy8zE11CxU9HqlWHHeRxfeN1tn8F7OEMVPIC9x1f8t3Z7US9ehQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lighthouse-logger/-/lighthouse-logger-2.0.2.tgz", + "integrity": "sha512-vWl2+u5jgOQuZR55Z1WM0XDdrJT6mzMP8zHUct7xTlWhuQs+eV0g+QL0RQdFjT54zVmbhLCP8vIVpy1wGn/gCg==", "dev": true, "license": "Apache-2.0", "dependencies": { - "debug": "^2.6.9", + "debug": "^4.4.1", "marky": "^1.2.2" } }, - "node_modules/lighthouse/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true, - "license": "MIT" - }, "node_modules/lighthouse/node_modules/open": { "version": "8.4.2", "resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz", @@ -3244,6 +3173,16 @@ "dev": true, "license": "MIT" }, + "node_modules/localforage": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz", + "integrity": "sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "lie": "3.1.1" + } + }, "node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -3264,6 +3203,13 @@ "dev": true, "license": "MIT" }, + "node_modules/lodash-es": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==", + "dev": true, + "license": "MIT" + }, "node_modules/lookup-closest-locale": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/lookup-closest-locale/-/lookup-closest-locale-6.2.0.tgz", @@ -3271,13 +3217,6 @@ "dev": true, "license": "MIT" }, - "node_modules/lru_map": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", - "integrity": "sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ==", - "dev": true, - "license": "MIT" - }, "node_modules/lru-cache": { "version": "7.18.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", @@ -3703,34 +3642,34 @@ } }, "node_modules/pa11y": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/pa11y/-/pa11y-8.0.0.tgz", - "integrity": "sha512-yMRsQT4Nc1peqpgx6kJiyK4fOPuVwXKMzIiBwqsKSlCmEm2JfESJskiGnBsdopG5xPAy18zs1wBhm7aghncNsg==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/pa11y/-/pa11y-9.0.1.tgz", + "integrity": "sha512-S0UReAkHQuGsjVDUNUKPREms3IyR/Dfrk6U2HMrjQ71LIdADmDJXrDOBOD05UroCn8Ns9jg2NgZeFuLj50Sl4w==", "dev": true, "license": "LGPL-3.0-only", "dependencies": { - "axe-core": "~4.8.4", - "bfj": "~8.0.0", - "commander": "~12.0.0", - "envinfo": "~7.11.1", + "axe-core": "~4.10.3", + "bfj": "~9.1.2", + "commander": "~13.1.0", + "envinfo": "~7.14.0", "html_codesniffer": "~2.5.1", "kleur": "~4.1.5", "mustache": "~4.2.0", "node.extend": "~2.0.3", - "puppeteer": "^22.3.0", - "semver": "~7.6.0" + "puppeteer": "^24.7.2", + "semver": "~7.7.1" }, "bin": { "pa11y": "bin/pa11y.js" }, "engines": { - "node": ">=18" + "node": ">=20" } }, "node_modules/pa11y/node_modules/axe-core": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.8.4.tgz", - "integrity": "sha512-CZLSKisu/bhJ2awW4kJndluz2HLZYIHh5Uy1+ZwDRkJi69811xgIXXfdU9HSLX0Th+ILrHj8qfL/5wzamsFtQg==", + "version": "4.10.3", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.10.3.tgz", + "integrity": "sha512-Xm7bpRXnDSX2YE2YFfBk2FnF0ep6tmG7xPh8iHee8MIcrgq762Nkce856dYtJYLkuIoYZvGfTs/PbZhideTcEg==", "dev": true, "license": "MPL-2.0", "engines": { @@ -3738,9 +3677,9 @@ } }, "node_modules/pa11y/node_modules/commander": { - "version": "12.0.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-12.0.0.tgz", - "integrity": "sha512-MwVNWlYjDTtOjX5PiD7o5pK0UrFU/OYgcJfjjK4RaHZETNtjJqrZa9Y9ds88+A+f+d5lv+561eZ+yCKoS3gbAA==", + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-13.1.0.tgz", + "integrity": "sha512-/rFeCpNJQbhSZjGVwO9RFV3xPqbnERS8MmIQzCtD/zl6gpJuV/bMLuN92oG3F7d8oDEHHRrujSXNUr8fpjntKw==", "dev": true, "license": "MIT", "engines": { @@ -3748,9 +3687,9 @@ } }, "node_modules/pa11y/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", "dev": true, "license": "ISC", "bin": { @@ -4048,46 +3987,57 @@ } }, "node_modules/puppeteer": { - "version": "22.15.0", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-22.15.0.tgz", - "integrity": "sha512-XjCY1SiSEi1T7iSYuxS82ft85kwDJUS7wj1Z0eGVXKdtr5g4xnVcbjwxhq5xBnpK/E7x1VZZoJDxpjAOasHT4Q==", + "version": "24.33.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-24.33.0.tgz", + "integrity": "sha512-nl3wsAztq5F8zybn4Tk41OCnYIzFIzGC6AN0WcF2KCUnWenajvRRPgBmS6LvNUV2HEeIzT2zRZHH0TgVxLDKew==", "dev": true, "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { - "@puppeteer/browsers": "2.3.0", + "@puppeteer/browsers": "2.11.0", + "chromium-bidi": "11.0.0", "cosmiconfig": "^9.0.0", - "devtools-protocol": "0.0.1312386", - "puppeteer-core": "22.15.0" + "devtools-protocol": "0.0.1534754", + "puppeteer-core": "24.33.0", + "typed-query-selector": "^2.12.0" }, "bin": { - "puppeteer": "lib/esm/puppeteer/node/cli.js" + "puppeteer": "lib/cjs/puppeteer/node/cli.js" }, "engines": { "node": ">=18" } }, "node_modules/puppeteer-core": { - "version": "22.15.0", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-22.15.0.tgz", - "integrity": "sha512-cHArnywCiAAVXa3t4GGL2vttNxh7GqXtIYGym99egkNJ3oG//wL9LkvO4WE8W1TJe95t1F1ocu9X4xWaGsOKOA==", + "version": "24.33.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-24.33.0.tgz", + "integrity": "sha512-tPTxVg+Qdj/8av4cy6szv3GlhxeOoNhiiMZ955fjxQyvPQE/6DjCa6ZyF/x0WJrlgBZtaLSP8TQgJb7FdLDXXA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@puppeteer/browsers": "2.3.0", - "chromium-bidi": "0.6.3", - "debug": "^4.3.6", - "devtools-protocol": "0.0.1312386", - "ws": "^8.18.0" + "@puppeteer/browsers": "2.11.0", + "chromium-bidi": "11.0.0", + "debug": "^4.4.3", + "devtools-protocol": "0.0.1534754", + "typed-query-selector": "^2.12.0", + "webdriver-bidi-protocol": "0.3.9", + "ws": "^8.18.3" }, "engines": { "node": ">=18" } }, + "node_modules/puppeteer-core/node_modules/devtools-protocol": { + "version": "0.0.1534754", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1534754.tgz", + "integrity": "sha512-26T91cV5dbOYnXdJi5qQHoTtUoNEqwkHcAyu/IKtjIAxiEqPMrDiRkDOPWVsGfNZGmlQVHQbZRSjD8sxagWVsQ==", + "dev": true, + "license": "BSD-3-Clause" + }, "node_modules/puppeteer-core/node_modules/ws": { - "version": "8.18.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz", - "integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==", + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", "dev": true, "license": "MIT", "engines": { @@ -4106,6 +4056,13 @@ } } }, + "node_modules/puppeteer/node_modules/devtools-protocol": { + "version": "0.0.1534754", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1534754.tgz", + "integrity": "sha512-26T91cV5dbOYnXdJi5qQHoTtUoNEqwkHcAyu/IKtjIAxiEqPMrDiRkDOPWVsGfNZGmlQVHQbZRSjD8sxagWVsQ==", + "dev": true, + "license": "BSD-3-Clause" + }, "node_modules/qs": { "version": "6.13.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", @@ -4290,24 +4247,35 @@ "license": "MIT" }, "node_modules/selenium-webdriver": { - "version": "4.22.0", - "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.22.0.tgz", - "integrity": "sha512-GNbrkCHmy249ai885wgXqTfqL2lZnclUH/P8pwTDIqzyFxU3YhDiN7p/c9tMFA4NhgRdEBO2QCG+CWmG7xr/Mw==", + "version": "4.35.0", + "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.35.0.tgz", + "integrity": "sha512-Baaeiuyu7BIIsSYf0SI7Mi55gsNmdI00KM0Hcofw1RnAY+0QEVpdh5yAxueDxgTZS8vcbGZFU0NJ6Qc1riIrLg==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/SeleniumHQ" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/selenium" + } + ], "license": "Apache-2.0", "dependencies": { + "@bazel/runfiles": "^6.3.1", "jszip": "^3.10.1", "tmp": "^0.2.3", - "ws": ">=8.16.0" + "ws": "^8.18.2" }, "engines": { - "node": ">= 14.21.0" + "node": ">= 20.0.0" } }, "node_modules/selenium-webdriver/node_modules/tmp": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", - "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", + "integrity": "sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==", "dev": true, "license": "MIT", "engines": { @@ -4315,9 +4283,9 @@ } }, "node_modules/selenium-webdriver/node_modules/ws": { - "version": "8.18.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.2.tgz", - "integrity": "sha512-DMricUmwGZUVr++AEAe2uiVM7UoO9MAVZMDu05UQOaUII0lp+zOzLLU4Xqh/JvTqklB1T4uELaaPBKyjE1r4fQ==", + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", "dev": true, "license": "MIT", "engines": { @@ -4679,17 +4647,15 @@ } }, "node_modules/streamx": { - "version": "2.22.0", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.22.0.tgz", - "integrity": "sha512-sLh1evHOzBy/iWRiR6d1zRcLao4gGZr3C1kzNz4fopCOKJb6xD9ub8Mpi9Mr1R6id5o43S+d93fI48UC5uM9aw==", + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.23.0.tgz", + "integrity": "sha512-kn+e44esVfn2Fa/O0CPFcex27fjIL6MkVae0Mm6q+E6f0hWv578YCERbv+4m02cjxvDsPKLnmxral/rR6lBMAg==", "dev": true, "license": "MIT", "dependencies": { + "events-universal": "^1.0.0", "fast-fifo": "^1.3.2", "text-decoder": "^1.1.0" - }, - "optionalDependencies": { - "bare-events": "^2.2.0" } }, "node_modules/string_decoder": { @@ -4846,9 +4812,9 @@ } }, "node_modules/tar-fs": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.9.tgz", - "integrity": "sha512-XF4w9Xp+ZQgifKakjZYmFdkLoSWd34VGKcsTCwlNWM7QG3ZbaxnTsaBwnjFZqHRf/rROxaR8rXnbtwdvaDI+lA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.1.1.tgz", + "integrity": "sha512-LZA0oaPOc2fVo82Txf3gw+AkEd38szODlptMYejQUhndHMLQ9M059uXR+AfS7DNo0NpINvSqDsvyaCrBVkptWg==", "dev": true, "license": "MIT", "dependencies": { @@ -4919,9 +4885,9 @@ } }, "node_modules/third-party-web": { - "version": "0.24.5", - "resolved": "https://registry.npmjs.org/third-party-web/-/third-party-web-0.24.5.tgz", - "integrity": "sha512-1rUOdMYpNTRajgk1F7CmHD26oA6rTKekBjHay854J6OkPXeNyPcR54rhWDaamlWyi9t2wAVPQESdedBhucmOLA==", + "version": "0.26.7", + "resolved": "https://registry.npmjs.org/third-party-web/-/third-party-web-0.26.7.tgz", + "integrity": "sha512-buUzX4sXC4efFX6xg2bw6/eZsCUh8qQwSavC4D9HpONMFlRbcHhD8Je5qwYdCpViR6q0qla2wPP+t91a2vgolg==", "dev": true, "license": "MIT" }, @@ -5030,6 +4996,13 @@ "node": ">= 0.6" } }, + "node_modules/typed-query-selector": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/typed-query-selector/-/typed-query-selector-2.12.0.tgz", + "integrity": "sha512-SbklCd1F0EiZOyPiW192rrHZzZ5sBijB6xM+cpmrwDqObvdtunOHHIk9fCGsoK5JVIYXoyEp4iEdE3upFH3PAg==", + "dev": true, + "license": "MIT" + }, "node_modules/typedarray-to-buffer": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", @@ -5040,17 +5013,6 @@ "is-typedarray": "^1.0.0" } }, - "node_modules/unbzip2-stream": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", - "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", - "dev": true, - "license": "MIT", - "dependencies": { - "buffer": "^5.2.1", - "through": "^2.3.8" - } - }, "node_modules/underscore": { "version": "1.12.1", "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.12.1.tgz", @@ -5088,13 +5050,6 @@ "node": ">= 0.8" } }, - "node_modules/urlpattern-polyfill": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/urlpattern-polyfill/-/urlpattern-polyfill-10.0.0.tgz", - "integrity": "sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==", - "dev": true, - "license": "MIT" - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -5132,6 +5087,13 @@ "node": ">= 0.8" } }, + "node_modules/webdriver-bidi-protocol": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/webdriver-bidi-protocol/-/webdriver-bidi-protocol-0.3.9.tgz", + "integrity": "sha512-uIYvlRQ0PwtZR1EzHlTMol1G0lAlmOe6wPykF9a77AK3bkpvZHzIVxRE2ThOx5vjy2zISe0zhwf5rzuUfbo1PQ==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/webidl-conversions": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", @@ -5545,9 +5507,9 @@ } }, "node_modules/zod": { - "version": "3.23.8", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.23.8.tgz", - "integrity": "sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==", + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", "dev": true, "license": "MIT", "funding": { diff --git a/package.json b/package.json index 6c33ae9..e953f43 100644 --- a/package.json +++ b/package.json @@ -10,11 +10,11 @@ "test:htmlcs": "htmlcs http://localhost:8080" }, "devDependencies": { - "@axe-core/cli": "^4.10.1", - "@lhci/cli": "^0.14.0", + "@axe-core/cli": "^4.11.0", + "@lhci/cli": "^0.15.1", "html_codesniffer": "^2.5.1", - "pa11y": "^8.0.0", - "puppeteer": "^22.15.0" + "pa11y": "^9.0.1", + "puppeteer": "^24.33.0" }, "overrides": { "glob": "^10.3.10", From 504f3b9a4b9a22ba2a7d1d0c194093b54586da37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roger=20Westerb=C3=B8?= Date: Sun, 14 Dec 2025 14:43:08 +0100 Subject: [PATCH 2/5] Add installation guides for Kea DHCP, Machine Classes, Proxmox, Physical Machine, and Talos Operator --- docs/howtoguide/install-keadhcp.md | 1 + docs/howtoguide/install-kubevirt.md | 58 ++++++- docs/howtoguide/install-machineclasses.md | 82 ++++++++++ docs/howtoguide/install-physical-machine.md | 3 + docs/howtoguide/install-proxmox.md | 14 ++ docs/howtoguide/install-talos.md | 1 + docs/howtoguide/setup-vitistack.md | 158 ++------------------ mkdocs.yml | 5 + 8 files changed, 176 insertions(+), 146 deletions(-) create mode 100644 docs/howtoguide/install-keadhcp.md create mode 100644 docs/howtoguide/install-machineclasses.md create mode 100644 docs/howtoguide/install-physical-machine.md create mode 100644 docs/howtoguide/install-proxmox.md create mode 100644 docs/howtoguide/install-talos.md diff --git a/docs/howtoguide/install-keadhcp.md b/docs/howtoguide/install-keadhcp.md new file mode 100644 index 0000000..7207471 --- /dev/null +++ b/docs/howtoguide/install-keadhcp.md @@ -0,0 +1 @@ +# Install Kea DHCP \ No newline at end of file diff --git a/docs/howtoguide/install-kubevirt.md b/docs/howtoguide/install-kubevirt.md index 2e17c4d..89422b7 100644 --- a/docs/howtoguide/install-kubevirt.md +++ b/docs/howtoguide/install-kubevirt.md @@ -1,4 +1,4 @@ -# Kubevirt +# Install Kubevirt ## Install kubevirt (docs with kind: https://kubevirt.io/quickstart_kind) @@ -37,4 +37,60 @@ ARCH=$(uname -s | tr A-Z a-z)-$(uname -m | sed 's/x86_64/amd64/') || windows-amd echo ${ARCH} curl -L -o virtctl https://github.com/kubevirt/kubevirt/releases/download/${VERSION}/virtctl-${VERSION}-${ARCH} sudo install -m 0755 virtctl /usr/local/bin +``` + +## Verify kubevirt components + +```bash +kubectl get kubevirt.kubevirt.io/kubevirt -n kubevirt -o=jsonpath="{.status.phase}" +``` + +Check the components +```bash +kubectl get all -n kubevirtkubectl get all -n kubevirt +``` + +## How create a KubeVirtConfig + +Create a k8s secret from file content (kubeconfig file to the kubevirt cluster) + +```bash +kubectl create secret generic kubevirt-provider --from-file=kubeconfig=` +``` + +Note, if you are using the supervisor cluster as the kubevirt cluster, use the kubernetes service address in the kubeconfig +```yaml +apiVersion: v1 +clusters: +- cluster: + server: https://kubernetes.default.svc:443 +.... +``` + +## Create the KubevirtConfig + +Create and modify this yaml + +Filename: kubevirtconfig.yaml +```yaml +apiVersion: vitistack.io/v1alpha1 +kind: KubevirtConfig +metadata: + name: kubevirt-provider +spec: + name: kubevirt-provider + secretNamespace: default + kubeconfigSecretRef: kubevirt-provider +``` + +And then: + +`kubectl apply -f kubevirtconfig.yaml` + + +## Install the Kubevirt-operator + +```bash +helm registry login ghcr.io +helm install viti-kubevirt-operator oci://ghcr.io/vitistack/helm/kubevirt-operator ``` \ No newline at end of file diff --git a/docs/howtoguide/install-machineclasses.md b/docs/howtoguide/install-machineclasses.md new file mode 100644 index 0000000..bd0949f --- /dev/null +++ b/docs/howtoguide/install-machineclasses.md @@ -0,0 +1,82 @@ +# Install Machine Classes + +These a example machine classes + +### Small +filename: machineclass-small.yaml +```yaml +apiVersion: vitistack.io/v1alpha1 +kind: MachineClass +metadata: + name: small +spec: + displayName: Small + description: Small instance with 2 cores and 8Gi memory + enabled: true + default: false + category: Standard + cpu: + cores: 2 + sockets: 1 + threads: 1 + memory: + quantity: 8Gi + machineProviders: [] +``` + +```bash +kubectl apply -f machineclass-small.yaml +``` + +### Medium +filename: machineclass-medium.yaml +```yaml +apiVersion: vitistack.io/v1alpha1 +kind: MachineClass +metadata: + name: medium +spec: + displayName: Medium + description: Medium instance with 4 cores and 16Gi memory + enabled: true + default: true + category: Standard + cpu: + cores: 4 + sockets: 1 + threads: 1 + memory: + quantity: 16Gi + machineProviders: [] + +``` + +```bash +kubectl apply -f machineclass-medium.yaml +``` + +### Large +filename: machineclass-large.yaml +```yaml +apiVersion: vitistack.io/v1alpha1 +kind: MachineClass +metadata: + name: large +spec: + displayName: Large + description: Large instance with 4 cores and 32Gi memory + enabled: true + default: false + category: Standard + cpu: + cores: 4 + sockets: 1 + threads: 1 + memory: + quantity: 32Gi + machineProviders: [] +``` + +```bash +kubectl apply -f machineclass-large.yaml +``` \ No newline at end of file diff --git a/docs/howtoguide/install-physical-machine.md b/docs/howtoguide/install-physical-machine.md new file mode 100644 index 0000000..696c610 --- /dev/null +++ b/docs/howtoguide/install-physical-machine.md @@ -0,0 +1,3 @@ +# Install physical machine + +To be continued \ No newline at end of file diff --git a/docs/howtoguide/install-proxmox.md b/docs/howtoguide/install-proxmox.md new file mode 100644 index 0000000..0132580 --- /dev/null +++ b/docs/howtoguide/install-proxmox.md @@ -0,0 +1,14 @@ +# Install Proxmox + +You need one or more Proxmox instances. + +To install proxmox, follow this installation guide: +- https://proxmox.com/en/products/proxmox-virtual-environment/get-started +- https://pve.proxmox.com/pve-docs/chapter-pve-installation.html + +## Install the Proxmox operator + +```bash +helm registry login ghcr.io +helm install viti-proxmox-operator oci://ghcr.io/vitistack/helm/proxmox-operator +``` \ No newline at end of file diff --git a/docs/howtoguide/install-talos.md b/docs/howtoguide/install-talos.md new file mode 100644 index 0000000..67689dd --- /dev/null +++ b/docs/howtoguide/install-talos.md @@ -0,0 +1 @@ +# Install Talos Operator \ No newline at end of file diff --git a/docs/howtoguide/setup-vitistack.md b/docs/howtoguide/setup-vitistack.md index 612b717..4ff5f6e 100644 --- a/docs/howtoguide/setup-vitistack.md +++ b/docs/howtoguide/setup-vitistack.md @@ -46,90 +46,14 @@ Or using kubectl (no authentication required) kubectl apply -f https://github.com/vitistack/common/releases/latest/download/crds.yaml ``` -## Machine classes -These a example machine classes - -### Small -filename: machineclass-small.yaml -```yaml -apiVersion: vitistack.io/v1alpha1 -kind: MachineClass -metadata: - name: small -spec: - displayName: Small - description: Small instance with 2 cores and 8Gi memory - enabled: true - default: false - category: Standard - cpu: - cores: 2 - sockets: 1 - threads: 1 - memory: - quantity: 8Gi - machineProviders: [] -``` +## Machine Classes +[Install machineclasses](install-machineclasses.md) -```bash -kubectl apply -f machineclass-small.yaml -``` +## DHCP -### Medium -filename: machineclass-medium.yaml -```yaml -apiVersion: vitistack.io/v1alpha1 -kind: MachineClass -metadata: - name: medium -spec: - displayName: Medium - description: Medium instance with 4 cores and 16Gi memory - enabled: true - default: true - category: Standard - cpu: - cores: 4 - sockets: 1 - threads: 1 - memory: - quantity: 16Gi - machineProviders: [] +We currently support: -``` - -```bash -kubectl apply -f machineclass-medium.yaml -``` - -### Large -filename: machineclass-large.yaml -```yaml -apiVersion: vitistack.io/v1alpha1 -kind: MachineClass -metadata: - name: large -spec: - displayName: Large - description: Large instance with 4 cores and 32Gi memory - enabled: true - default: false - category: Standard - cpu: - cores: 4 - sockets: 1 - threads: 1 - memory: - quantity: 32Gi - machineProviders: [] -``` - -```bash -kubectl apply -f machineclass-large.yaml -``` - -## Kea Operator -To be continued +- [Kea DHCP](install-keadhcp.md) ## Vitistack operator @@ -141,73 +65,17 @@ Install the vitistack operator by: helm install vitistack-operator oci://ghcr.io/vitistack/helm/vitistack-operator ``` -## Kubevirt -To create machines with kubevirt we need to install kubevirt into a own cluster (or into the supervisor cluster) - -### To install kubevirt -[Guide to install Kubevirt](install-kubevirt.md) +## Vitistack Machine Providers +To make vitistack machines, we currently support -### Verify kubevirt components - -```bash -kubectl get kubevirt.kubevirt.io/kubevirt -n kubevirt -o=jsonpath="{.status.phase}" -``` +- [Kubevirt](./install-kubevirt.md) +- [Proxmox](./install-proxmox.md) +- [Physical](./install-physical-machine.md) -Check the components -```bash -kubectl get all -n kubevirtkubectl get all -n kubevirt -``` -### How create a KubeVirtConfig +## Vitistack Kubernetes Providers -Create a k8s secret from file content (kubeconfig file to the kubevirt cluster) +To install a vitistack Kubernetes cluster, we currently support -```bash -kubectl create secret generic kubevirt-provider --from-file=kubeconfig=` -``` - -### Create the KubevirtConfig - -Create and modify this yaml - -Filename: kubevirtconfig.yaml -```yaml -apiVersion: vitistack.io/v1alpha1 -kind: KubevirtConfig -metadata: - name: kubevirt-provider -spec: - name: kubevirt-provider - secretNamespace: default - kubeconfigSecretRef: kubevirt-provider -``` - -And then: - -`kubectl apply -f kubevirtconfig.yaml` - - -### Install the Kubevirt-operator - -```bash -helm registry login ghcr.io -helm install viti-kubevirt-operator oci://ghcr.io/vitistack/helm/kubevirt-operator -``` - -## Proxmox-operator - -You need one or more Proxmox instances. - -To install proxmox, follow this installation guide: -- https://proxmox.com/en/products/proxmox-virtual-environment/get-started -- https://pve.proxmox.com/pve-docs/chapter-pve-installation.html - -### Install the Proxmox operator - -```bash -helm registry login ghcr.io -helm install viti-proxmox-operator oci://ghcr.io/vitistack/helm/proxmox-operator -``` +- [Talos](./install-talos.md) -## Talos Operator -To be continued \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 7e5a16a..e6b7ac1 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -78,7 +78,12 @@ nav: - How-to-guides: - howtoguide/index.md - howtoguide/setup-vitistack.md + - howtoguide/install-machineclasses.md + - howtoguide/install-keadhcp.md - howtoguide/install-kubevirt.md + - howtoguide/install-proxmox.md + - howtoguide/install-physical-machine.md + - howtoguide/install-talos.md - howtoguide/argocd_ipam-api.md - Reference: - reference/index.md From e89041eeadb7e86f59aff101e8d80a82b3d32784 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roger=20Westerb=C3=B8?= Date: Sun, 14 Dec 2025 15:32:14 +0100 Subject: [PATCH 3/5] Update installation guides for Kubevirt and Proxmox operators with corrected helm install commands and added Proxmox secret creation instructions --- docs/howtoguide/install-kubevirt.md | 2 +- docs/howtoguide/install-proxmox.md | 49 ++++++++++++++++++++++++++++- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/docs/howtoguide/install-kubevirt.md b/docs/howtoguide/install-kubevirt.md index 89422b7..c586927 100644 --- a/docs/howtoguide/install-kubevirt.md +++ b/docs/howtoguide/install-kubevirt.md @@ -92,5 +92,5 @@ And then: ```bash helm registry login ghcr.io -helm install viti-kubevirt-operator oci://ghcr.io/vitistack/helm/kubevirt-operator +helm install vitistack-kubevirt-operator oci://ghcr.io/vitistack/helm/kubevirt-operator ``` \ No newline at end of file diff --git a/docs/howtoguide/install-proxmox.md b/docs/howtoguide/install-proxmox.md index 0132580..5910dd6 100644 --- a/docs/howtoguide/install-proxmox.md +++ b/docs/howtoguide/install-proxmox.md @@ -8,7 +8,54 @@ To install proxmox, follow this installation guide: ## Install the Proxmox operator +Setup the kubernetes secret for Proxmox: + +Existing secret containing Proxmox credentials +The secret should contain: PROXMOX_ENDPOINT, PROXMOX_USERNAME, PROXMOX_PASSWORD +or PROXMOX_TOKEN_ID, PROXMOX_TOKEN_SECRET + +### Create the secret with: +```bash +kubectl create secret generic proxmox-credentials-secret \ + --from-literal=PROXMOX_ENDPOINT=https://proxmox.example.com:8006/api2/json \ + --from-literal=PROXMOX_USERNAME=root@pam \ + --from-literal=PROXMOX_PASSWORD=yourpassword +``` + +### Or for token auth: +```bash +kubectl create secret generic proxmox-credentials-secret \ + --from-literal=PROXMOX_ENDPOINT=https://proxmox.example.com:8006/api2/json \ + --from-literal=PROXMOX_TOKEN_ID=root@pam!mytoken \ + --from-literal=PROXMOX_TOKEN_SECRET=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx +``` + +### or with yaml +Filename: proxmox-credentials-secret.yaml +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: proxmox-credentials-secret +type: Opaque +stringData: + PROXMOX_ENDPOINT: "https://proxmox.example.com:8006/api2/json" + # Use username/password auth: + PROXMOX_USERNAME: "root@pam" + PROXMOX_PASSWORD: "yourpassword" + # OR use token auth (comment out username/password above): + # PROXMOX_TOKEN_ID: "root@pam!mytoken" + # PROXMOX_TOKEN_SECRET: "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" +``` + +Apply with + +```bash +kubectl apply -f proxmox-credentials-secret.yaml +``` + +### Install the Vitistack Proxmox Operator ```bash helm registry login ghcr.io -helm install viti-proxmox-operator oci://ghcr.io/vitistack/helm/proxmox-operator +helm install vitistack-proxmox-operator oci://ghcr.io/vitistack/helm/proxmox-operator ``` \ No newline at end of file From e7032bb8e15a52742253c44c3cd8723763e0b2f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roger=20Westerb=C3=B8?= Date: Sun, 14 Dec 2025 20:32:21 +0100 Subject: [PATCH 4/5] Add installation guides and examples for Kea DHCP, Kubevirt, Proxmox, Talos, and example machines --- docs/howtoguide/example-kubernetesclusters.md | 66 ++++++ docs/howtoguide/example-machines.md | 73 +++++++ docs/howtoguide/install-keadhcp.md | 198 ++++++++++++++++- docs/howtoguide/install-kubevirt.md | 201 ++++++++++++++++++ docs/howtoguide/install-proxmox.md | 193 +++++++++++++++++ docs/howtoguide/install-talos.md | 184 +++++++++++++++- mkdocs.yml | 2 + 7 files changed, 915 insertions(+), 2 deletions(-) create mode 100644 docs/howtoguide/example-kubernetesclusters.md create mode 100644 docs/howtoguide/example-machines.md diff --git a/docs/howtoguide/example-kubernetesclusters.md b/docs/howtoguide/example-kubernetesclusters.md new file mode 100644 index 0000000..a995381 --- /dev/null +++ b/docs/howtoguide/example-kubernetesclusters.md @@ -0,0 +1,66 @@ +# Example KubernetesClusters + +## Small simple kubernetescluster + +```yaml +apiVersion: vitistack.io/v1alpha1 +kind: KubernetesCluster +metadata: + name: t-test-002-5tu8 +spec: + data: + clusterUid: "a30fbc8d-596f-48d0-8541-dbc23bca28a1" + clusterId: "t-test-002-5tu8" + provider: talos + environment: dev + datacenter: test-south-az1 + project: simple-project + region: south + workorder: "simple-workorder" + zone: "az1" + workspace: "simple-workspace" + topology: + version: "1.34.1" + controlplane: + replicas: 1 + version: "1.34.1" + machineClass: small + provider: kubevirt + storage: + - class: "standard" + path: "/var/lib/vitistack/kubevirt" + size: "20Gi" + metadata: + annotations: + environment: development + region: west-trondelag + labels: + environment: development + region: west-trondelag + workers: + nodePools: + - name: wp + taint: [] + version: "1.34.1" + replicas: 1 + machineClass: large + autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 5 + scalingRules: + - "cpu" + metadata: + annotations: + environment: development + region: west-trondelag + labels: + environment: development + region: west-trondelag + provider: kubevirt + storage: + - class: "standard" + path: "/var/lib/vitistack/kubevirt" + size: "20Gi" + +``` \ No newline at end of file diff --git a/docs/howtoguide/example-machines.md b/docs/howtoguide/example-machines.md new file mode 100644 index 0000000..f29eb42 --- /dev/null +++ b/docs/howtoguide/example-machines.md @@ -0,0 +1,73 @@ +# Example Machines + +## Debian iso +```yaml +--- +apiVersion: vitistack.io/v1alpha1 +kind: Machine +metadata: + name: example-machine-iso-debian + annotations: + # Annotation to indicate we want to use a DataVolume for the boot source + kubevirt.io/boot-source: "datavolume" + kubevirt.io/boot-source-type: "http" +spec: + machineClass: "medium" + name: "debian-iso-vm" + provider: kubevirt + + # Operating system configuration + os: + family: linux + distribution: debian + version: "13.2" + architecture: amd64 + # HTTP URL to the debian ISO image + # This will be used to create a DataVolume with CDI + imageID: "https://cdimage.debian.org/debian-cd/current/amd64/iso-cd/debian-13.2.0-amd64-netinst.iso" + + # Define disks - the ISO will be attached as a cdrom + disks: + - name: "root" + sizeGB: 50 + boot: true + type: "virtio" + encrypted: false + +``` + +## Talos iso +```yaml +--- +apiVersion: vitistack.io/v1alpha1 +kind: Machine +metadata: + name: example-machine-iso-talos + annotations: + # Annotation to indicate we want to use a DataVolume for the boot source + kubevirt.io/boot-source: "datavolume" + kubevirt.io/boot-source-type: "http" +spec: + machineClass: "medium" + name: "talos-iso-vm" + provider: kubevirt + + # Operating system configuration + os: + family: linux + distribution: talos + version: "1.11.5" + architecture: amd64 + # HTTP URL to the Talos ISO image + # This will be used to create a DataVolume with CDI + imageID: "https://github.com/siderolabs/talos/releases/download/v1.11.5/metal-amd64.iso" + + # Define disks - the ISO will be attached as a cdrom + disks: + - name: "root" + sizeGB: 50 + boot: true + type: "virtio" + encrypted: false + +``` \ No newline at end of file diff --git a/docs/howtoguide/install-keadhcp.md b/docs/howtoguide/install-keadhcp.md index 7207471..95058f9 100644 --- a/docs/howtoguide/install-keadhcp.md +++ b/docs/howtoguide/install-keadhcp.md @@ -1 +1,197 @@ -# Install Kea DHCP \ No newline at end of file +# Install Kea DHCP + +You need a instance of Kea DHCP, please read this doc for installation and configuration: https://kea.readthedocs.io/en/stable + +## Install Kea-operator + +```bash +helm registry login ghcr.io +helm install vitistack-kea-operator oci://ghcr.io/vitistack/helm/kea-operator +``` + +Values.yaml from helm chart +```yaml +# Default values for kea-operator. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# This will set the replicaset count more information can be found here: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/ +replicaCount: 1 + +# This sets the container image more information can be found here: https://kubernetes.io/docs/concepts/containers/images/ +image: + repository: ghcr.io/vitistack/kea-operator + # This sets the pull policy for images. + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "" + +# This is for the secrets for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ +imagePullSecrets: [] +# This is to override the chart name. +nameOverride: "" +fullnameOverride: "" + +# This section builds out the service account more information can be found here: https://kubernetes.io/docs/concepts/security/service-accounts/ +serviceAccount: + # Specifies whether a service account should be created + create: true + # Automatically mount a ServiceAccount's API credentials? + automount: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + +# This is for setting Kubernetes Annotations to a Pod. +# For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ +podAnnotations: {} +# This is for setting Kubernetes Labels to a Pod. +# For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ +podLabels: {} + +podSecurityContext: + fsGroup: 65532 + +securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 65532 + runAsGroup: 65532 + seccompProfile: + type: RuntimeDefault + +# This is for setting up a service more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/ +service: + # This sets the service type more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: ClusterIP + # This sets the ports more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#field-spec-ports + port: 80 + +# This block is for setting up the ingress for more information can be found here: https://kubernetes.io/docs/concepts/services-networking/ingress/ +ingress: + enabled: false + className: "" + annotations: + {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + hosts: + - host: chart-example.local + paths: + - path: / + pathType: ImplementationSpecific + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 100m + memory: 128Mi + +# This is to setup the liveness and readiness probes more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ +livenessProbe: + httpGet: + path: /healthz + port: 9995 + initialDelaySeconds: 15 + periodSeconds: 20 +readinessProbe: + httpGet: + path: /readyz + port: 9995 + initialDelaySeconds: 5 + periodSeconds: 10 + +# This section is for setting up autoscaling more information can be found here: https://kubernetes.io/docs/concepts/workloads/autoscaling/ +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 100 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +# Additional volumes on the output Deployment definition. +volumes: [] +# - name: foo +# secret: +# secretName: mysecret +# optional: false + +# Additional volumeMounts on the output Deployment definition. +volumeMounts: [] +# - name: foo +# mountPath: "/etc/foo" +# readOnly: true + +nodeSelector: {} + +tolerations: [] + +affinity: {} + +# KEA DHCP server configuration +kea: + # Primary KEA server URL (e.g., https://kea-dhcp.example.com:8000) + url: "" + # Secondary KEA server URL for HA failover (optional) + secondaryUrl: "" + # KEA server port (used if url doesn't include port) + port: "8000" + # Timeout in seconds for KEA API requests + timeoutSeconds: "10" + # Disable HTTP keep-alive connections + disableKeepalives: "true" + # Comma-separated list of required client classes for pools + requireClientClasses: "biosclients,ueficlients,ipxeclients" + + # Basic authentication credentials + # These should be overridden in your ArgoCD app or values override + auth: + username: "" + password: "" + # Reference to an existing secret containing credentials + # If set, username/password above are ignored + existingSecret: "" + # Key in the secret for username + usernameKey: "username" + # Key in the secret for password + passwordKey: "password" + + # TLS configuration + tls: + enabled: "false" + insecure: "false" + serverName: "" + # Path to CA certificate file (mounted via volumes) + caFile: "" + # Path to client certificate file (for mTLS) + certFile: "" + # Path to client key file (for mTLS) + keyFile: "" + # Reference to an existing secret containing TLS certificates + secretName: "" + secretNamespace: "" + +# Logging configuration +logging: + level: "info" + jsonLogging: "true" + colorize: "false" + addCaller: "true" + disableStacktrace: "false" + unescapeMultiline: "false" + +# Development mode +development: "false" +``` \ No newline at end of file diff --git a/docs/howtoguide/install-kubevirt.md b/docs/howtoguide/install-kubevirt.md index c586927..991d888 100644 --- a/docs/howtoguide/install-kubevirt.md +++ b/docs/howtoguide/install-kubevirt.md @@ -50,6 +50,33 @@ Check the components kubectl get all -n kubevirtkubectl get all -n kubevirt ``` +## Multus + +The Vitistack uses Multus together with Kubevirt, so please install multus. + +Docs: https://github.com/k8snetworkplumbingwg/multus-cni and https://github.com/k8snetworkplumbingwg/multus-cni/blob/master/docs/quickstart.md + + +## Containerized Data Importer (CDI) + +Notice, this is an experimental feature from Kubevirt + +Docs: https://kubevirt.io/labs/kubernetes/lab2.html + +"You can experiment with this lab online at Killercoda +In this lab, you will learn how to use Containerized Data Importer (CDI) to import Virtual Machine images for use with Kubevirt. CDI simplifies the process of importing data from various sources into Kubernetes Persistent Volumes, making it easier to use that data within your virtual machines. + +CDI introduces DataVolumes, custom resources meant to be used as abstractions of PVCs. A custom controller watches for DataVolumes and handles the creation of a target PVC with all the spec and annotations required for importing the data. Depending on the type of source, other specific CDI controller will start the import process and create a raw image named disk.img with the desired content into the target PVC." + + +To install: + +```bash +export VERSION=$(basename $(curl -s -w %{redirect_url} https://github.com/kubevirt/containerized-data-importer/releases/latest)) +kubectl create -f https://github.com/kubevirt/containerized-data-importer/releases/download/$VERSION/cdi-operator.yaml +kubectl create -f https://github.com/kubevirt/containerized-data-importer/releases/download/$VERSION/cdi-cr.yaml +``` + ## How create a KubeVirtConfig Create a k8s secret from file content (kubeconfig file to the kubevirt cluster) @@ -93,4 +120,178 @@ And then: ```bash helm registry login ghcr.io helm install vitistack-kubevirt-operator oci://ghcr.io/vitistack/helm/kubevirt-operator +``` + +Values.yaml from Helm chart: +```yaml +# Default values for kubevirt-operator. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# This will set the replicaset count more information can be found here: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/ +replicaCount: 1 + +# This sets the container image more information can be found here: https://kubernetes.io/docs/concepts/containers/images/ +image: + repository: ghcr.io/vitistack/kubevirt-operator + # This sets the pull policy for images. + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "" + +# This is for the secrets for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ +imagePullSecrets: [] +# This is to override the chart name. +nameOverride: "" +fullnameOverride: "" + +# This section builds out the service account more information can be found here: https://kubernetes.io/docs/concepts/security/service-accounts/ +serviceAccount: + # Specifies whether a service account should be created + create: true + # Automatically mount a ServiceAccount's API credentials? + automount: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + +# This is for setting Kubernetes Annotations to a Pod. +# For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ +podAnnotations: {} +# This is for setting Kubernetes Labels to a Pod. +# For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ +podLabels: {} + +podSecurityContext: + fsGroup: 2000 + +securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 1000 + seccompProfile: + type: RuntimeDefault + +# This is for setting up a service more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/ +service: + # This sets the service type more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: ClusterIP + # This sets the ports more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#field-spec-ports + port: 80 + +resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 100m + memory: 128Mi + +# This is to setup the liveness and readiness probes more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ +livenessProbe: + httpGet: + path: /healthz + port: 9992 + initialDelaySeconds: 15 + periodSeconds: 20 +readinessProbe: + httpGet: + path: /readyz + port: 9992 + initialDelaySeconds: 5 + periodSeconds: 10 + +# This section is for setting up autoscaling more information can be found here: https://kubernetes.io/docs/concepts/workloads/autoscaling/ +autoscaling: + enabled: true + minReplicas: 1 + maxReplicas: 100 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +# Additional volumes on the output Deployment definition. +volumes: [] +# - name: foo +# secret: +# secretName: mysecret +# optional: false + +# Additional volumeMounts on the output Deployment definition. +volumeMounts: [] +# - name: foo +# mountPath: "/etc/foo" +# readOnly: true + +nodeSelector: {} + +tolerations: [] + +affinity: {} + +# Operator configuration +# These settings are passed as environment variables to the operator + +# Namespace the operator manages (uses Release.Namespace if empty) +namespace: "" +# CPU model for VMs: "host-model" (default for x86), "host-passthrough" (required for ARM) +cpuModel: "" +# CNI version for NetworkAttachmentDefinitions +nadCniVersion: "1.0.0" +# Where to fetch public IPs from: "vmi" (default, from KubeVirt VMI) or "networkconfiguration" +ipSource: "vmi" +# Enable Containerized Data Importer (CDI) support +kubevirtSupportCDI: false +# Name of the MachineProvider +machineProviderName: "kubevirt-provider" +# PVC volume mode: "Block" (default) or "Filesystem" +pvcVolumeMode: "Block" +# Optional prefix for VM names +vmNamePrefix: "" +# Vitistack name (optional) +vitistackName: "vitistack" + +# Logging configuration +logging: + # Log level: debug, info, warn, error + level: "info" + # Output logs as JSON + json: true + # Add caller information to logs + addCaller: false + # Disable stacktrace in logs + disableStacktrace: true + # Unescape multiline log messages + unescapedMultiline: false + # Colorize log lines (for development) + colorizeLine: false + +# Leader election for HA deployments +leaderElection: + enabled: true + +# Metrics configuration +metrics: + # Enable metrics endpoint + enabled: true + # Metrics bind address (use ":8443" for HTTPS, ":8080" for HTTP, "0" to disable) + bindAddress: ":8443" + # Serve metrics over HTTPS + secure: true + +# Health probe configuration +healthProbe: + # Health probe bind address + bindAddress: ":9992" + +# RBAC configuration +rbac: + # Create ClusterRole and ClusterRoleBinding + create: true + ``` \ No newline at end of file diff --git a/docs/howtoguide/install-proxmox.md b/docs/howtoguide/install-proxmox.md index 5910dd6..6e9f1cb 100644 --- a/docs/howtoguide/install-proxmox.md +++ b/docs/howtoguide/install-proxmox.md @@ -58,4 +58,197 @@ kubectl apply -f proxmox-credentials-secret.yaml ```bash helm registry login ghcr.io helm install vitistack-proxmox-operator oci://ghcr.io/vitistack/helm/proxmox-operator +``` + +Values.yaml from helm chart: +```yaml +# Default values for proxmox-operator. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# This will set the replicaset count more information can be found here: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/ +replicaCount: 1 + +# This sets the container image more information can be found here: https://kubernetes.io/docs/concepts/containers/images/ +image: + repository: ghcr.io/vitistack/viti-proxmox-operator + # This sets the pull policy for images. + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "" + +# This is for the secrets for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ +imagePullSecrets: [] +# This is to override the chart name. +nameOverride: "" +fullnameOverride: "" + +# This section builds out the service account more information can be found here: https://kubernetes.io/docs/concepts/security/service-accounts/ +serviceAccount: + # Specifies whether a service account should be created + create: true + # Automatically mount a ServiceAccount's API credentials? + automount: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + +# This is for setting Kubernetes Annotations to a Pod. +# For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ +podAnnotations: {} +# This is for setting Kubernetes Labels to a Pod. +# For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ +podLabels: {} + +podSecurityContext: + runAsNonRoot: true + fsGroup: 65532 + +securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 65532 + runAsGroup: 65532 + seccompProfile: + type: RuntimeDefault + +# This is for setting up a service more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/ +service: + # This sets the service type more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: ClusterIP + # This sets the ports more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#field-spec-ports + port: 8081 + +resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 100m + memory: 128Mi + +# This is to setup the liveness and readiness probes more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ +livenessProbe: + httpGet: + path: /healthz + port: 8081 + initialDelaySeconds: 15 + periodSeconds: 20 +readinessProbe: + httpGet: + path: /readyz + port: 8081 + initialDelaySeconds: 5 + periodSeconds: 10 + +# This section is for setting up autoscaling more information can be found here: https://kubernetes.io/docs/concepts/workloads/autoscaling/ +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 100 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +# Additional volumes on the output Deployment definition. +volumes: [] +# - name: foo +# secret: +# secretName: mysecret +# optional: false + +# Additional volumeMounts on the output Deployment definition. +volumeMounts: [] +# - name: foo +# mountPath: "/etc/foo" +# readOnly: true + +nodeSelector: {} + +tolerations: [] + +affinity: {} + +# Existing secret containing Proxmox credentials +# The secret should contain: PROXMOX_ENDPOINT, PROXMOX_USERNAME, PROXMOX_PASSWORD +# or PROXMOX_TOKEN_ID, PROXMOX_TOKEN_SECRET +# Create the secret with: +# kubectl create secret generic proxmox-credentials-secret \ +# --from-literal=PROXMOX_ENDPOINT=https://proxmox.example.com:8006/api2/json \ +# --from-literal=PROXMOX_USERNAME=root@pam \ +# --from-literal=PROXMOX_PASSWORD=yourpassword +# Or for token auth: +# kubectl create secret generic proxmox-credentials-secret \ +# --from-literal=PROXMOX_ENDPOINT=https://proxmox.example.com:8006/api2/json \ +# --from-literal=PROXMOX_TOKEN_ID=root@pam!mytoken \ +# --from-literal=PROXMOX_TOKEN_SECRET=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx +existingSecret: "proxmox-credentials-secret" + +# Logging configuration +logging: + # Log level (debug, info, warn, error) + level: "info" + # Output logs in JSON format + json: true + +# Proxmox connection settings (required) +proxmox: + # Proxmox API endpoint URL (e.g., https://proxmox.example.com:8006/api2/json) + endpoint: "" + # Authentication - use either username/password OR token + # Username authentication (e.g., root@pam) + username: "" + password: "" + # Token authentication (alternative to username/password) + tokenId: "" + tokenSecret: "" + # Skip TLS certificate verification (not recommended for production) + insecureTLS: false + +# VM management settings +vm: + # Starting VM ID for new machines + idStart: 2000 + # Node selection strategy: first, random, round-robin + nodeSelection: "first" + # Comma-separated list of allowed nodes (empty means all nodes) + allowedNodes: "" + # Default storage pool for VM disks + defaultStorage: "local-lvm" + # Default network bridge for VMs + defaultNetwork: "vmbr0" + # Network model for VM interfaces (virtio, e1000, e1000e, rtl8139, vmxnet3) + # virtio = VirtIO paravirtualized (best performance) + networkModel: "virtio" + # Default VLAN tag for VM network interfaces (0 = no VLAN tagging) + defaultVlan: 0 + # Default MTU for VM network interfaces (0 = use Proxmox default of 1500) + # Common values: 1500 (standard), 9000 (jumbo frames) + defaultMtu: 0 + # Default CPU type (e.g., host, kvm64, x86-64-v2-AES) + defaultCpuType: "x86-64-v2-AES" + # Enable NUMA for VMs + enableNuma: true + # SCSI controller type + scsiController: "virtio-scsi-single" + # Enable QEMU Guest Agent (required for network status) + enableQemuAgent: true + # Start VM immediately after creation + startOnCreate: true + +# Network configuration settings +network: + # IP address source for VMs: + # - "proxmox": Get IP from Proxmox/QEMU Guest Agent (default) + # - "networkconfiguration": Get IP from NetworkConfiguration CRD (Kea DHCP reservation) + ipSource: "proxmox" + # Second octet for MAC address generation (format: 02:XX:RR:RR:RR:RR where XX is this value) + # Default is 24 (0x18 in hex), resulting in MAC addresses like 02:18:XX:XX:XX:XX + macSet: "24" + ``` \ No newline at end of file diff --git a/docs/howtoguide/install-talos.md b/docs/howtoguide/install-talos.md index 67689dd..de6e3f8 100644 --- a/docs/howtoguide/install-talos.md +++ b/docs/howtoguide/install-talos.md @@ -1 +1,183 @@ -# Install Talos Operator \ No newline at end of file +# Install Talos Operator + +```bash +helm registry login ghcr.io +helm install vitistack-talos-operator oci://ghcr.io/vitistack/helm/talos-operator +``` + +Values.yaml from Helm chart +```yaml +# Default values for talos-operator. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +# This will set the replicaset count more information can be found here: https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/ +replicaCount: 1 + +# This sets the container image more information can be found here: https://kubernetes.io/docs/concepts/containers/images/ +image: + repository: ghcr.io/vitistack/talos-operator + # This sets the pull policy for images. + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "" + +# This is for the secrets for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ +imagePullSecrets: [] +# This is to override the chart name. +nameOverride: "" +fullnameOverride: "" + +# Talos Operator Configuration +# Endpoint mode determines how the operator configures control plane endpoints. +# Valid values: +# - "none": Use control plane IPs directly (no load balancing) +# - "networkconfiguration": Use ControlPlaneVirtualSharedIP from NetworkNamespace (default) +# - "talosvip": Use Talos built-in VIP (requires additional Talos configuration) +# - "custom": Use user-provided endpoint addresses +endpointMode: "networkconfiguration" + +# Custom endpoint addresses (only used when endpointMode is "custom") +# Can be a single IP/hostname or comma-separated list +customEndpoint: "" + +# Boot image source configuration +# Valid values: "pxe", "bootimage" +# Default: "pxe" (uses PXE boot for machine provisioning) +bootImageSource: "pxe" + +# Boot image URL (only used when bootImageSource is "bootimage") +bootImage: "" + +# Log configuration +logLevel: "info" +logJson: true + +# Secret prefix for cluster secrets +secretPrefix: "" + +# Vitistack name +vitistackName: "vitistack" + +# Kubernetes provider name +kubernetesProviderName: "talos-provider" + +# Tenant configuration +tenant: + configMapName: "talos-tenant-config" + configMapNamespace: "default" + configMapDataKey: "config.yaml" + +# Talos configuration +talos: + version: "v1.11.5" + defaultKubernetesVersion: "1.34.1" + predictableNetworkNames: true + vmInstallImage: + kubevirt: "factory.talos.dev/metal-installer/ce4c980550dd2ab1b17bbf2b08801c7eb59418eafe8f279833297925d67c7515:v1.11.5" + default: "factory.talos.dev/metal-installer/ce4c980550dd2ab1b17bbf2b08801c7eb59418eafe8f279833297925d67c7515:v1.11.5" + +# This section builds out the service account more information can be found here: https://kubernetes.io/docs/concepts/security/service-accounts/ +serviceAccount: + # Specifies whether a service account should be created + create: true + # Automatically mount a ServiceAccount's API credentials? + automount: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + +# This is for setting Kubernetes Annotations to a Pod. +# For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ +podAnnotations: {} +# This is for setting Kubernetes Labels to a Pod. +# For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ +podLabels: {} + +podSecurityContext: + fsGroup: 2000 + +securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + runAsUser: 1000 + seccompProfile: + type: RuntimeDefault + +# This is for setting up a service more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/ +service: + # This sets the service type more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types + type: ClusterIP + # This sets the ports more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#field-spec-ports + port: 9993 + +resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 100m + memory: 128Mi + +# This is to setup the liveness and readiness probes more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/ +livenessProbe: + httpGet: + path: /healthz + port: 9993 +readinessProbe: + httpGet: + path: /readyz + port: 9993 + +# This section is for setting up autoscaling more information can be found here: https://kubernetes.io/docs/concepts/workloads/autoscaling/ +# Note: Operators typically run as single instances with leader election enabled +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 3 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +# Additional volumes on the output Deployment definition. +volumes: [] +# - name: foo +# secret: +# secretName: mysecret +# optional: false + +# Additional volumeMounts on the output Deployment definition. +volumeMounts: [] +# - name: foo +# mountPath: "/etc/foo" +# readOnly: true + +nodeSelector: {} + +tolerations: [] + +affinity: {} + +# Extra environment variables to add to the container +# Example: +# extraEnv: +# - name: MY_VAR +# value: "my-value" +extraEnv: [] + +# Environment variables from Secrets or ConfigMaps +# Use this for sensitive data - reference existing secrets/configmaps +# Example: +# envFrom: +# - secretRef: +# name: my-secret +# - configMapRef: +# name: my-configmap +envFrom: [] + +``` \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index e6b7ac1..ad2bada 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -84,6 +84,8 @@ nav: - howtoguide/install-proxmox.md - howtoguide/install-physical-machine.md - howtoguide/install-talos.md + - howtoguide/example-machines.md + - howtoguide/example-kubernetesclusters.md - howtoguide/argocd_ipam-api.md - Reference: - reference/index.md From ec0b8d358b275abd8cb450af4dbf78a525b3cd24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roger=20Westerb=C3=B8?= Date: Sun, 14 Dec 2025 22:24:03 +0100 Subject: [PATCH 5/5] Add CDI dependency notes for Debian and Talos ISO examples --- docs/howtoguide/example-machines.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/howtoguide/example-machines.md b/docs/howtoguide/example-machines.md index f29eb42..69eca1d 100644 --- a/docs/howtoguide/example-machines.md +++ b/docs/howtoguide/example-machines.md @@ -1,6 +1,9 @@ # Example Machines ## Debian iso + +Dependent on the experimental feature CDI (https://kubevirt.io/user-guide/storage/containerized_data_importer) + ```yaml --- apiVersion: vitistack.io/v1alpha1 @@ -33,10 +36,12 @@ spec: boot: true type: "virtio" encrypted: false - ``` ## Talos iso + +Dependent on the experimental feature CDI (https://kubevirt.io/user-guide/storage/containerized_data_importer) + ```yaml --- apiVersion: vitistack.io/v1alpha1 @@ -69,5 +74,4 @@ spec: boot: true type: "virtio" encrypted: false - -``` \ No newline at end of file +```