James Read 1 miesiąc temu
rodzic
commit
3f937c98ba
100 zmienionych plików z 490 dodań i 13 usunięć
  1. 12 7
      .github/workflows/build-and-release.yml
  2. 34 0
      .github/workflows/docs-antora.yml
  3. 3 1
      .gitignore
  4. 1 0
      CONTRIBUTING.adoc
  5. 3 3
      Dockerfile.multiarches
  6. 2 2
      Dockerfile.singlearch
  7. 2 0
      README.md
  8. 15 0
      docs/antora.yml
  9. 40 0
      docs/modules/ROOT/check_chevron_links.py
  10. 24 0
      docs/modules/ROOT/check_no_h1.py
  11. 25 0
      docs/modules/ROOT/check_unnavigable.py
  12. 15 0
      docs/modules/ROOT/examples/action_customization/icons/config.yaml
  13. 9 0
      docs/modules/ROOT/examples/k8s_configmap.yml
  14. 37 0
      docs/modules/ROOT/examples/k8s_deployment.yml
  15. 21 0
      docs/modules/ROOT/examples/k8s_ingress.yml
  16. 19 0
      docs/modules/ROOT/examples/reverse-proxies/etc/npm-docker-compose.yml
  17. 25 0
      docs/modules/ROOT/examples/reverse-proxies/etc/reverse_proxy_nginx_dns.conf
  18. 48 0
      docs/modules/ROOT/examples/solutions/container-control-panel/config/config.yaml
  19. 2 0
      docs/modules/ROOT/examples/solutions/container-control-panel/config/containers.json
  20. 32 0
      docs/modules/ROOT/examples/solutions/directory-actions/config.yaml
  21. 28 0
      docs/modules/ROOT/examples/solutions/heating-control-panel/configs/config.yaml
  22. 2 0
      docs/modules/ROOT/examples/solutions/heating-control-panel/configs/heating.yaml
  23. 35 0
      docs/modules/ROOT/examples/solutions/primitive-password/password.js
  24. 36 0
      docs/modules/ROOT/examples/solutions/systemd-control-panel/config/config.yaml
  25. 4 0
      docs/modules/ROOT/examples/solutions/systemd-control-panel/config/systemd_units.json
  26. 10 0
      docs/modules/ROOT/examples/solutions/wol/config.yaml
  27. 6 0
      docs/modules/ROOT/examples/solutions/wol/config_docker.yaml
  28. BIN
      docs/modules/ROOT/images/action-button-iconify.png
  29. BIN
      docs/modules/ROOT/images/action-confirmation.png
  30. BIN
      docs/modules/ROOT/images/additionalNavigationLinks.png
  31. BIN
      docs/modules/ROOT/images/arg-datetime.png
  32. BIN
      docs/modules/ROOT/images/arg-suggestions-chrome.png
  33. BIN
      docs/modules/ROOT/images/arg-suggestions-firefox.png
  34. BIN
      docs/modules/ROOT/images/args-choices-entities.png
  35. BIN
      docs/modules/ROOT/images/args-choices-exec.png
  36. BIN
      docs/modules/ROOT/images/args-multiline-text.png
  37. BIN
      docs/modules/ROOT/images/args1.png
  38. BIN
      docs/modules/ROOT/images/args2.png
  39. BIN
      docs/modules/ROOT/images/args3.png
  40. BIN
      docs/modules/ROOT/images/args4.png
  41. BIN
      docs/modules/ROOT/images/authentik_login.png
  42. BIN
      docs/modules/ROOT/images/authentik_login2.png
  43. BIN
      docs/modules/ROOT/images/authentik_login3.png
  44. BIN
      docs/modules/ROOT/images/authentik_new_app.png
  45. BIN
      docs/modules/ROOT/images/authentik_provider_config.png
  46. BIN
      docs/modules/ROOT/images/authentik_provider_secrets.png
  47. BIN
      docs/modules/ROOT/images/authentik_select_oauth2.png
  48. BIN
      docs/modules/ROOT/images/blocked.png
  49. BIN
      docs/modules/ROOT/images/dashboard-display.png
  50. BIN
      docs/modules/ROOT/images/dashboard-heating-control-panel.png
  51. BIN
      docs/modules/ROOT/images/dashboard.png
  52. BIN
      docs/modules/ROOT/images/defaultUiHideNav.png
  53. BIN
      docs/modules/ROOT/images/defaultUiWithNav.png
  54. BIN
      docs/modules/ROOT/images/diagnostics.png
  55. BIN
      docs/modules/ROOT/images/directory-actions-screenshot.png
  56. BIN
      docs/modules/ROOT/images/exampleIcons.png
  57. BIN
      docs/modules/ROOT/images/executionButtons.png
  58. BIN
      docs/modules/ROOT/images/executionDialog.png
  59. BIN
      docs/modules/ROOT/images/fieldset.png
  60. BIN
      docs/modules/ROOT/images/flashyButton.png
  61. BIN
      docs/modules/ROOT/images/folders.png
  62. BIN
      docs/modules/ROOT/images/gitops.png
  63. BIN
      docs/modules/ROOT/images/hacs-custom-repo.png
  64. BIN
      docs/modules/ROOT/images/hacs-download.png
  65. BIN
      docs/modules/ROOT/images/hacs-dropdown.png
  66. BIN
      docs/modules/ROOT/images/hacs-search.png
  67. BIN
      docs/modules/ROOT/images/hass-add-integration.png
  68. BIN
      docs/modules/ROOT/images/hass-buttons.png
  69. BIN
      docs/modules/ROOT/images/hass-configure-integration.png
  70. BIN
      docs/modules/ROOT/images/hass-devices-and-services.png
  71. BIN
      docs/modules/ROOT/images/hassButtonSetup.png
  72. BIN
      docs/modules/ROOT/images/hassConfigYaml.png
  73. BIN
      docs/modules/ROOT/images/hassFileEditor.png
  74. BIN
      docs/modules/ROOT/images/hassFileEditorConfig.png
  75. BIN
      docs/modules/ROOT/images/hello-world.png
  76. BIN
      docs/modules/ROOT/images/iconify.png
  77. BIN
      docs/modules/ROOT/images/icons/Discord.png
  78. BIN
      docs/modules/ROOT/images/icons/GitHub.png
  79. BIN
      docs/modules/ROOT/images/icons/OliveTinLogo.png
  80. BIN
      docs/modules/ROOT/images/maxRate.png
  81. BIN
      docs/modules/ROOT/images/mrGreenAction.png
  82. BIN
      docs/modules/ROOT/images/mre.png
  83. BIN
      docs/modules/ROOT/images/mrgreen.gif
  84. BIN
      docs/modules/ROOT/images/npm.png
  85. BIN
      docs/modules/ROOT/images/page-title.png
  86. BIN
      docs/modules/ROOT/images/pocketid.png
  87. BIN
      docs/modules/ROOT/images/popupOutputOnly.png
  88. BIN
      docs/modules/ROOT/images/portDiagram.png
  89. BIN
      docs/modules/ROOT/images/sidebar.png
  90. BIN
      docs/modules/ROOT/images/snapshot-archive.png
  91. BIN
      docs/modules/ROOT/images/snapshot-download.png
  92. BIN
      docs/modules/ROOT/images/snapshots.png
  93. BIN
      docs/modules/ROOT/images/solution-k8s-hosted.png
  94. BIN
      docs/modules/ROOT/images/solution-systemd-control-panel.png
  95. BIN
      docs/modules/ROOT/images/solutions/container-control-panel/preview.png
  96. BIN
      docs/modules/ROOT/images/solutions/wol/preview.png
  97. BIN
      docs/modules/ROOT/images/ssh-diagram.png
  98. BIN
      docs/modules/ROOT/images/stream-deck/config.png
  99. BIN
      docs/modules/ROOT/images/stream-deck/inputs.png
  100. BIN
      docs/modules/ROOT/images/stream-deck/marketplace.png

+ 12 - 7
.github/workflows/build-and-release.yml

@@ -17,25 +17,30 @@ jobs:
     runs-on: ubuntu-latest
     steps:
       - name: Checkout
-        uses: actions/checkout@v4
+        uses: actions/checkout@v6
         with:
           fetch-depth: 0
 
       - name: Set up QEMU
         id: qemu
-        uses: docker/setup-qemu-action@v3
+        uses: docker/setup-qemu-action@v4
         with:
           image: tonistiigi/binfmt:latest
           platforms: arm64,arm
 
-      - name: Setup node
-        uses: actions/setup-node@v4
+      - name: Setup node (npm cache)
+        if: github.event_name != 'pull_request'
+        uses: actions/setup-node@v6.4.0
         with:
           cache: 'npm'
           cache-dependency-path: frontend/package-lock.json
 
+      - name: Setup node
+        if: github.event_name == 'pull_request'
+        uses: actions/setup-node@v6.4.0
+
       - name: Setup Go
-        uses: actions/setup-go@v5
+        uses: actions/setup-go@v6
         with:
           go-version-file: 'service/go.mod'
           cache: true
@@ -45,7 +50,7 @@ jobs:
         run: go version
 
       - name: Login to Docker Hub
-        uses: docker/login-action@v3
+        uses: docker/login-action@v4
         with:
           username: ${{ secrets.DOCKERHUB_USERNAME }}
           password: ${{ secrets.DOCKERHUB_KEY }}
@@ -74,7 +79,7 @@ jobs:
         run: cd integration-tests && make -w
 
       - name: Archive integration tests
-        uses: actions/upload-artifact@v4.3.1
+        uses: actions/upload-artifact@v7
         if: always()
         with:
           name: "OliveTin-integration-tests-${{ env.DATE }}-${{ github.sha }}"

+ 34 - 0
.github/workflows/docs-antora.yml

@@ -0,0 +1,34 @@
+name: Antora docs
+on:
+  push:
+    paths:
+      - 'docs/**'
+      - 'local-antora-playbook.yml'
+      - 'local-antora-playbook-ci.yml'
+      - '.github/workflows/docs-antora.yml'
+  pull_request:
+    paths:
+      - 'docs/**'
+      - 'local-antora-playbook.yml'
+      - 'local-antora-playbook-ci.yml'
+      - '.github/workflows/docs-antora.yml'
+
+jobs:
+  antora:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout repository
+        uses: actions/checkout@v4
+        with:
+          fetch-depth: 0
+
+      - name: Install Node.js
+        uses: actions/setup-node@v4
+        with:
+          node-version: '20'
+
+      - name: Install Antora toolchain
+        run: npm i antora@3.1.14 asciidoctor-kroki@0.18.1 @asciidoctor/tabs@1.0.0-beta.6
+
+      - name: Generate docs site (smoke)
+        run: npx antora local-antora-playbook-ci.yml --log-level info

+ 3 - 1
.gitignore

@@ -19,4 +19,6 @@ OliveTin
 integration-tests/configs/authRequireGuestsToLogin/sessions.yaml
 webui
 webui.dev
-sessions.yaml
+sessions.yaml
+docs/build/
+build/

+ 1 - 0
CONTRIBUTING.adoc

@@ -58,6 +58,7 @@ make
 The project layout is reasonably straightforward;
 
 * See the `Makefile` for common targets. This project was originally created on top of Fedora, but it should be usable on Debian/your faveourite distro with minor changes (if any).
+* End-user documentation (AsciiDoc for link:https://docs.olivetin.app[docs.olivetin.app]) lives in `docs/` as an Antora component; the published site is built from the separate link:https://github.com/OliveTin/docs.olivetin.app[docs.olivetin.app] repository.
 * The API is defined in protobuf+Connect RPC - you will need to `make proto`.
 * The Go daemon is built from the `cmd` and `internal` directories mostly.
 * The webui is just a single page application with a bit of Javascript in the `webui` directory. This can happily be hosted on another webserver.

+ 3 - 3
Dockerfile.multiarches

@@ -1,17 +1,17 @@
 # Multi-arch Dockerfile for GoReleaser (dockers_v2).
-# Base image :43 is used without arch suffix so the registry can supply the right
+# Base image :44 is used without arch suffix so the registry can supply the right
 # platform (manifest list). TARGETPLATFORM is set by BuildKit for COPY.
 # For custom/local single-arch builds, use Dockerfile.singlearch instead.
 
 ARG TARGETPLATFORM
 
-FROM registry.fedoraproject.org/fedora-minimal:43 AS olivetin-tmputils
+FROM registry.fedoraproject.org/fedora-minimal:44 AS olivetin-tmputils
 
 RUN microdnf -y install dnf-plugins-core && \
 	dnf-3 config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo && \
 	microdnf install -y docker-ce-cli docker-compose-plugin && microdnf clean all
 
-FROM registry.fedoraproject.org/fedora-minimal:43
+FROM registry.fedoraproject.org/fedora-minimal:44
 
 LABEL org.opencontainers.image.source https://github.com/OliveTin/OliveTin
 LABEL org.opencontainers.image.title OliveTin

+ 2 - 2
Dockerfile.singlearch

@@ -1,10 +1,10 @@
-FROM --platform=linux/amd64 registry.fedoraproject.org/fedora-minimal:43-x86_64 AS olivetin-tmputils
+FROM --platform=linux/amd64 registry.fedoraproject.org/fedora-minimal:44-x86_64 AS olivetin-tmputils
 
 RUN microdnf -y install dnf-plugins-core && \
 	dnf-3 config-manager --add-repo https://download.docker.com/linux/fedora/docker-ce.repo && \
 	microdnf install -y docker-ce-cli docker-compose-plugin && microdnf clean all
 
-FROM --platform=linux/amd64 registry.fedoraproject.org/fedora-minimal:43-x86_64
+FROM --platform=linux/amd64 registry.fedoraproject.org/fedora-minimal:44-x86_64
 
 LABEL org.opencontainers.image.source https://github.com/OliveTin/OliveTin
 LABEL org.opencontainers.image.title OliveTin

+ 2 - 0
README.md

@@ -20,6 +20,8 @@
 
 All documentation can be found at [docs.olivetin.app](https://docs.olivetin.app). This includes installation and usage guide, etc.
 
+The AsciiDoc sources for that site live in this repository under [`docs/`](docs/) (Antora component). The [docs.olivetin.app](https://github.com/OliveTin/docs.olivetin.app) repository contains the Antora playbook, theme supplemental files, and the workflow that publishes GitHub Pages.
+
 ## Use cases
 
 **Safely** give access to commands, for less technical people;

+ 15 - 0
docs/antora.yml

@@ -0,0 +1,15 @@
+---
+name: ROOT
+title: OliveTin
+version: ''
+display_version: 'Version 3k'
+start_page: index.adoc
+asciidoc:
+  attributes:
+    source-language: asciidoc@
+    table-caption: false
+    toclevels: 2
+nav:
+- modules/ROOT/nav.adoc
+
+

+ 40 - 0
docs/modules/ROOT/check_chevron_links.py

@@ -0,0 +1,40 @@
+#!/usr/bin/env python3
+
+import glob
+import re
+
+nav_file = open('nav.adoc', 'r')
+nav_string = nav_file.read()
+
+adoc_files = glob.glob('pages/**/*.adoc', recursive=True)
+
+filelist = dict()
+
+for file in adoc_files:
+    with open(file, 'r') as handle:
+        content = handle.read()
+
+        matches = re.findall(r'<<(.*?),?([\w\- ]+)>>', content)
+
+        for match in matches:
+            m = match
+
+            if match[0] == "":
+                m = match[1]
+            else:
+                m = match[0]
+
+            if content.count("#" + m) != 1:
+                if file not in filelist:
+                    filelist[file] = list()
+
+                filelist[file].append(m)
+
+
+print("Files:", len(filelist))
+
+for file in filelist.keys():
+    print(file)
+
+    for match in filelist[file]:
+        print("\t", match)

+ 24 - 0
docs/modules/ROOT/check_no_h1.py

@@ -0,0 +1,24 @@
+#!/usr/bin/env python3
+
+import glob
+import re
+
+adoc_files = glob.glob('pages/**/*.adoc', recursive=True)
+
+filelist = list()
+
+for file in adoc_files:
+    with open(file, 'r') as handle:
+        content = handle.read()
+
+        matches = re.findall('^= ', content, re.MULTILINE)
+
+        if len(matches) == 0:
+            filelist.append(file)
+
+
+print("Files:", len(filelist))
+
+for file in filelist:
+    print(file)
+

+ 25 - 0
docs/modules/ROOT/check_unnavigable.py

@@ -0,0 +1,25 @@
+#!/usr/bin/env python3
+
+# find .adoc files that are not navigable from the nav.adoc file
+
+import glob
+
+nav_file = open('nav.adoc', 'r')
+nav_string = nav_file.read()
+
+adoc_files = glob.glob('pages/**/*.adoc', recursive=True)
+
+unnavigable_files = []
+
+for file in adoc_files:
+    filename = file.replace("pages/", "")
+
+    if filename not in nav_string:
+        unnavigable_files.append(filename)
+
+
+unnavigable_files = sorted(unnavigable_files)
+
+print("Unnavigable files:", len(unnavigable_files))
+for file in unnavigable_files:
+    print(file)

+ 15 - 0
docs/modules/ROOT/examples/action_customization/icons/config.yaml

@@ -0,0 +1,15 @@
+actions:
+  - title: Unicode (emoji) alias icon
+    shell: echo "Hello!"
+    icon: smile
+
+  - title: Unicode (emoji) icon
+    shell: echo "Hello!"
+    icon: "&#128526;"
+
+  - title: Iconify Icon
+    icon: <iconify-icon icon="ant-design:bug-filled"></iconify-icon>
+
+  - title: HTML Image (jpg/png/gif/etc) icon
+    shell: echo "Hello!"
+    icon: '<img src = "custom-webui/icons/mrgreen.gif" style = "width: 1em;" />'

+ 9 - 0
docs/modules/ROOT/examples/k8s_configmap.yml

@@ -0,0 +1,9 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+  name: olivetin-config
+data:
+  config.yaml: |
+    actions:
+      - title: "Hello world!"
+        shell: echo 'Hello World!'

+ 37 - 0
docs/modules/ROOT/examples/k8s_deployment.yml

@@ -0,0 +1,37 @@
+apiVersion: apps/v1
+kind: Deployment
+metadata: 
+    name: olivetin
+spec: 
+  replicas: 1
+  selector: 
+    matchLabels:
+      app: olivetin
+  template:
+    metadata:
+      labels:
+        app: olivetin
+    spec:
+      containers: 
+        - name: olivetin
+          image: docker.io/jamesread/olivetin:latest
+          ports:
+            - containerPort: 1337
+          volumeMounts:
+            - name: olivetin-config
+              mountPath: "/config"
+              readOnly: true
+
+          livenessProbe:
+            exec:
+              command: 
+                - curl 
+                - localhost:1337
+            initialDelaySeconds: 5
+            periodSeconds: 30
+
+      volumes:
+        - name: olivetin-config
+          configMap: 
+            name: olivetin-config
+

+ 21 - 0
docs/modules/ROOT/examples/k8s_ingress.yml

@@ -0,0 +1,21 @@
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata: 
+  name: olivetin-ingress
+spec:
+  defaultBackend: 
+    service: 
+      name: olivetin
+      port:
+        number: 1337
+  rules:
+    - host: olivetin.apps.ocp.teratan.net
+      http:
+        paths:
+          - path: /
+            pathType: Prefix
+            backend:
+              service:
+                name: olivetin
+                port:
+                  number: 1337

+ 19 - 0
docs/modules/ROOT/examples/reverse-proxies/etc/npm-docker-compose.yml

@@ -0,0 +1,19 @@
+services:
+  app:
+    image: 'jc21/nginx-proxy-manager:latest'
+    restart: unless-stopped
+    ports:
+      - '80:80'
+      - '81:81'
+      - '443:443'
+    volumes:
+      - ./data:/data
+      - ./letsencrypt:/etc/letsencrypt
+  olivetin:
+    container_name: olivetin
+    image: jamesread/olivetin
+    volumes:
+      - ./OliveTin:/config # replace host path or volume as needed
+    ports:
+      - "1337:1337"
+    restart: unless-stopped

+ 25 - 0
docs/modules/ROOT/examples/reverse-proxies/etc/reverse_proxy_nginx_dns.conf

@@ -0,0 +1,25 @@
+server {
+    listen 443 ssl;
+
+    ssl_certificate "/etc/nginx/conf.d/server.crt";
+    ssl_certificate_key "/etc/nginx/conf.d/server.key";
+
+    access_log  /var/log/nginx/ot.access.log  main;
+    error_log /var/log/nginx/ot.error.log notice;
+
+    server_name olivetin.example.com;
+
+    location / {
+        proxy_pass http://localhost:1337/;
+        proxy_redirect http://localhost:1337/ http://localhost/OliveTin/;
+    }
+
+    location /websocket {
+        proxy_set_header Upgrade "websocket";
+        proxy_set_header Connection "upgrade";
+        proxy_pass http://localhost:1337/websocket;
+        proxy_read_timeout 600s;
+        proxy_send_timeout 600s;
+    }
+}
+

+ 48 - 0
docs/modules/ROOT/examples/solutions/container-control-panel/config/config.yaml

@@ -0,0 +1,48 @@
+# This config has two actions which are applied to all "container" entities 
+# found in the entity file.
+#
+# Docs: http://localhost/docs.olivetin.app/docs/entities.html
+actions:
+  - title: Start {{ container.Names }}
+    icon: box
+    shell: docker start {{ container.Names }}
+    entity: container
+    triggers:
+      - Update container entity file
+
+  - title: Stop {{ container.Names }}
+    icon: box
+    shell: docker stop {{ container.Names }}
+    entity: container
+    triggers:
+      - Update container entity file
+
+  # This is a hidden action, that is run on startup, and every 5 minutes, and 
+  # when the above start/stop commands are run (see the `triggers` property).
+
+  - title: Update container entity file
+    shell: 'docker ps -a --format json > /etc/OliveTin/entities/containers.json'
+    hidden: true
+    execOnStartup: true
+    execOnCron: '*/5 * * * *'
+
+# Docs: http://docs.olivetin.app/entities.html
+entities:
+  - file: /etc/OliveTin/entities/containers.json
+    name: container
+
+# The only way to properly use entities, are to use them with a `fieldset` on
+# a dashboard.
+dashboards:
+  # This is the second dashboard.
+  - title: My Containers
+    contents:
+      - title: 'Container {{ container.Names }} ({{ container.Image }})'
+        entity: container
+        type: fieldset
+        contents:
+          - type: display
+            title: |
+              {{ container.RunningFor }} <br /><br /><strong>{{ container.State }}</strong>
+          - title: 'Start {{ container.Names }}'
+          - title: 'Stop {{ container.Names }}'

+ 2 - 0
docs/modules/ROOT/examples/solutions/container-control-panel/config/containers.json

@@ -0,0 +1,2 @@
+{"Command":"\"/bin/bash\"","CreatedAt":"2024-02-28 22:33:35 +0000 GMT","ID":"fcf468e18a0e","Image":"fedora","Labels":"maintainer=Clement Verna \u003ccverna@fedoraproject.org\u003e","LocalVolumes":"0","Mounts":"","Names":"minecraft","Networks":"bridge","Ports":"","RunningFor":"3 minutes ago","Size":"0B","State":"created","Status":"Created"}
+{"Command":"\"/bin/bash\"","CreatedAt":"2024-02-23 23:18:57 +0000 GMT","ID":"442dd6fe316a","Image":"fedora","Labels":"maintainer=Clement Verna \u003ccverna@fedoraproject.org\u003e","LocalVolumes":"0","Mounts":"","Names":"brave_shirley","Networks":"bridge","Ports":"","RunningFor":"4 days ago","Size":"0B","State":"created","Status":"Created"}

+ 32 - 0
docs/modules/ROOT/examples/solutions/directory-actions/config.yaml

@@ -0,0 +1,32 @@
+actions:
+  - title: check log directory
+    hidden: true
+    shell: |
+      function addDirectory {
+        COUNT=$(ls -l $1 | wc -l)
+        echo "- directory: $1" >> /etc/OliveTin/entities/directories.yaml
+        echo "  count: $COUNT" >> /etc/OliveTin/entities/directories.yaml
+      }
+
+      truncate -s 0 /etc/OliveTin/entities/directories.yaml
+      addDirectory /var/log/
+      addDirectory /home/xconspirisist/logs
+    execOnStartup: true
+    execOnCron: "* * * * *"
+
+  - title: clean {{ log_directory.directory }} ({{log_directory.count }} files)
+    shell: |
+      echo "Removing all files in {{ log_directory.directory }}"
+    entity: log_directory
+
+entities:
+  - name: log_directory
+    file: /etc/OliveTin/entities/directories.yaml
+
+dashboards:
+  - title: Log Actions
+    contents:
+      - entity: log_directory
+        type: fieldset
+        contents:
+          - title: clean {{ log_directory.directory }} ({{log_directory.count }} files)

+ 28 - 0
docs/modules/ROOT/examples/solutions/heating-control-panel/configs/config.yaml

@@ -0,0 +1,28 @@
+logLevel: "INFO"
+
+actions:
+  - title: Turn heating up
+    icon: '&#128316;'
+    shell: /opt/heating.sh up
+
+  - title: Turn heating down
+    icon: '&#128317;'
+    shell: /opt/heating.sh down
+
+entities:
+  - file: /etc/OliveTin/entities/heating.yaml
+    name: heating
+
+dashboards:
+  - title: Heating Control Panel
+    contents:
+      - title: "{{ heater.title }}"
+        entity: heating
+        type: fieldset
+        contents:
+          - type: display
+            title: |
+              <span class = "icon">&#127777;</span> <br />{{ heating.temperature }}
+
+          - title: Turn heating up
+          - title: Turn heating down

+ 2 - 0
docs/modules/ROOT/examples/solutions/heating-control-panel/configs/heating.yaml

@@ -0,0 +1,2 @@
+- title: Main heater
+  temperature: 20 degrees

+ 35 - 0
docs/modules/ROOT/examples/solutions/primitive-password/password.js

@@ -0,0 +1,35 @@
+const myPassword = 'sekrit'
+
+const domMain = document.getElementsByTagName('main')[0]
+domMain.style.display = 'none'
+
+const domPassword = document.createElement('input')
+const domLogin = document.createElement('button')
+
+function checkPassword () {
+  if (domPassword.value === myPassword) {
+    domMain.style.display = 'block'
+    domPassword.remove()
+    domLogin.remove()
+  } else {
+    window.alert('Incorrect password. Please try again.')
+  }
+}
+
+function setupPasswordForm () {
+  domPassword.setAttribute('type', 'password')
+  domPassword.addEventListener('keydown', (e) => {
+    if (e.key === 'Enter') {
+      checkPassword()
+    }
+  })
+
+  domLogin.innerText = 'Login'
+  domLogin.onclick = checkPassword
+
+  const domHeader = document.querySelector('header')
+  domHeader.appendChild(domPassword)
+  domHeader.appendChild(domLogin)
+}
+
+document.addEventListener('DOMContentLoaded', setupPasswordForm)

+ 36 - 0
docs/modules/ROOT/examples/solutions/systemd-control-panel/config/config.yaml

@@ -0,0 +1,36 @@
+actions:
+  - title: Stop {{ systemd_unit.unit }}
+    shell: systemctl stop {{ systemd_unit.unit }}
+    icon: <iconify-icon icon="zondicons:hand-stop"></iconify-icon>
+    entity: systemd_unit
+    triggers:
+      - Update services file
+
+  - title: Start {{ systemd_unit.unit }}
+    shell: systemctl start {{ systemd_unit.unit }}
+    icon: <iconify-icon icon="ic:round-directions-run"></iconify-icon>
+    entity: systemd_unit
+    triggers:
+      - Update services file
+
+  - title: Update services file
+    shell: systemctl list-units -a -o json --no-pager | jq -c 'map(select (.unit | contains ("upsilon", "podman", "boot.mount"))) | .[]'  > /etc/OliveTin/entities/systemd_units.json
+    hidden: true
+    execOnStartup: true
+
+entities:
+  - file: /etc/OliveTin/entities/systemd_units.json
+    name: systemd_unit
+
+dashboards:
+  - title: My Services
+    contents:
+      - title: '{{ systemd_unit.description }}'
+        type: fieldset
+        entity: systemd_unit
+        contents:
+          - title: 'Status: {{ systemd_unit.sub }}'
+            type: display
+
+          - title: Start {{ systemd_unit.unit }}
+          - title: Stop {{ systemd_unit.unit }}

+ 4 - 0
docs/modules/ROOT/examples/solutions/systemd-control-panel/config/systemd_units.json

@@ -0,0 +1,4 @@
+{"unit":"boot.mount","load":"loaded","active":"active","sub":"mounted","description":"/boot"}
+{"unit":"podman.service","load":"loaded","active":"inactive","sub":"dead","description":"Podman API Service"}
+{"unit":"upsilon-drone.service","load":"loaded","active":"active","sub":"running","description":"upsilon-drone"}
+{"unit":"podman.socket","load":"loaded","active":"active","sub":"listening","description":"Podman API Socket"}

+ 10 - 0
docs/modules/ROOT/examples/solutions/wol/config.yaml

@@ -0,0 +1,10 @@
+actions:
+  - title: WakeOnLan Server1
+    shell: ether-wake A8:5E:45:E4:FF:2A
+    icon: ping
+
+  - title: Install ether-wake on startup
+    shell: microdnf install -y net-tools
+    hidden: true
+    execOnStartup: true
+    timeout: 120

+ 6 - 0
docs/modules/ROOT/examples/solutions/wol/config_docker.yaml

@@ -0,0 +1,6 @@
+  - title: WakeOnLan Server1
+    # The r0gger/docker-wake-on-lan is a minimal container for WOL
+    # that can be run on the host network.
+    # It is not required to run the OliveTin container on the host network.
+    shell: |
+     docker run --rm --name wake-on-lan --net=host -e MAC='A8:5E:45:E4:FF:2A' r0gger/docker-wake-on-lan

BIN
docs/modules/ROOT/images/action-button-iconify.png


BIN
docs/modules/ROOT/images/action-confirmation.png


BIN
docs/modules/ROOT/images/additionalNavigationLinks.png


BIN
docs/modules/ROOT/images/arg-datetime.png


BIN
docs/modules/ROOT/images/arg-suggestions-chrome.png


BIN
docs/modules/ROOT/images/arg-suggestions-firefox.png


BIN
docs/modules/ROOT/images/args-choices-entities.png


BIN
docs/modules/ROOT/images/args-choices-exec.png


BIN
docs/modules/ROOT/images/args-multiline-text.png


BIN
docs/modules/ROOT/images/args1.png


BIN
docs/modules/ROOT/images/args2.png


BIN
docs/modules/ROOT/images/args3.png


BIN
docs/modules/ROOT/images/args4.png


BIN
docs/modules/ROOT/images/authentik_login.png


BIN
docs/modules/ROOT/images/authentik_login2.png


BIN
docs/modules/ROOT/images/authentik_login3.png


BIN
docs/modules/ROOT/images/authentik_new_app.png


BIN
docs/modules/ROOT/images/authentik_provider_config.png


BIN
docs/modules/ROOT/images/authentik_provider_secrets.png


BIN
docs/modules/ROOT/images/authentik_select_oauth2.png


BIN
docs/modules/ROOT/images/blocked.png


BIN
docs/modules/ROOT/images/dashboard-display.png


BIN
docs/modules/ROOT/images/dashboard-heating-control-panel.png


BIN
docs/modules/ROOT/images/dashboard.png


BIN
docs/modules/ROOT/images/defaultUiHideNav.png


BIN
docs/modules/ROOT/images/defaultUiWithNav.png


BIN
docs/modules/ROOT/images/diagnostics.png


BIN
docs/modules/ROOT/images/directory-actions-screenshot.png


BIN
docs/modules/ROOT/images/exampleIcons.png


BIN
docs/modules/ROOT/images/executionButtons.png


BIN
docs/modules/ROOT/images/executionDialog.png


BIN
docs/modules/ROOT/images/fieldset.png


BIN
docs/modules/ROOT/images/flashyButton.png


BIN
docs/modules/ROOT/images/folders.png


BIN
docs/modules/ROOT/images/gitops.png


BIN
docs/modules/ROOT/images/hacs-custom-repo.png


BIN
docs/modules/ROOT/images/hacs-download.png


BIN
docs/modules/ROOT/images/hacs-dropdown.png


BIN
docs/modules/ROOT/images/hacs-search.png


BIN
docs/modules/ROOT/images/hass-add-integration.png


BIN
docs/modules/ROOT/images/hass-buttons.png


BIN
docs/modules/ROOT/images/hass-configure-integration.png


BIN
docs/modules/ROOT/images/hass-devices-and-services.png


BIN
docs/modules/ROOT/images/hassButtonSetup.png


BIN
docs/modules/ROOT/images/hassConfigYaml.png


BIN
docs/modules/ROOT/images/hassFileEditor.png


BIN
docs/modules/ROOT/images/hassFileEditorConfig.png


BIN
docs/modules/ROOT/images/hello-world.png


BIN
docs/modules/ROOT/images/iconify.png


BIN
docs/modules/ROOT/images/icons/Discord.png


BIN
docs/modules/ROOT/images/icons/GitHub.png


BIN
docs/modules/ROOT/images/icons/OliveTinLogo.png


BIN
docs/modules/ROOT/images/maxRate.png


BIN
docs/modules/ROOT/images/mrGreenAction.png


BIN
docs/modules/ROOT/images/mre.png


BIN
docs/modules/ROOT/images/mrgreen.gif


BIN
docs/modules/ROOT/images/npm.png


BIN
docs/modules/ROOT/images/page-title.png


BIN
docs/modules/ROOT/images/pocketid.png


BIN
docs/modules/ROOT/images/popupOutputOnly.png


BIN
docs/modules/ROOT/images/portDiagram.png


BIN
docs/modules/ROOT/images/sidebar.png


BIN
docs/modules/ROOT/images/snapshot-archive.png


BIN
docs/modules/ROOT/images/snapshot-download.png


BIN
docs/modules/ROOT/images/snapshots.png


BIN
docs/modules/ROOT/images/solution-k8s-hosted.png


BIN
docs/modules/ROOT/images/solution-systemd-control-panel.png


BIN
docs/modules/ROOT/images/solutions/container-control-panel/preview.png


BIN
docs/modules/ROOT/images/solutions/wol/preview.png


BIN
docs/modules/ROOT/images/ssh-diagram.png


BIN
docs/modules/ROOT/images/stream-deck/config.png


BIN
docs/modules/ROOT/images/stream-deck/inputs.png


BIN
docs/modules/ROOT/images/stream-deck/marketplace.png


Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików