diff --git a/oepl-proxy/.devcontainer/Dockerfile b/oepl-proxy/.devcontainer/Dockerfile new file mode 100644 index 0000000..5985892 --- /dev/null +++ b/oepl-proxy/.devcontainer/Dockerfile @@ -0,0 +1,46 @@ +FROM mcr.microsoft.com/vscode/devcontainers/base:debian + +WORKDIR /workspaces + +SHELL ["/bin/bash", "-o", "pipefail", "-c"] + +# Set Docker daemon config +RUN \ + mkdir -p /etc/docker \ + && echo '{"storage-driver": "vfs"}' > /etc/docker/daemon.json + +# Installa aditional tools +RUN \ + apt-get update \ + && apt-get install -y --no-install-recommends \ + dbus \ + network-manager \ + libpulse0 \ + xz-utils + +# Install docker +RUN apt-get update && apt-get install -y --no-install-recommends \ + apt-transport-https \ + ca-certificates \ + curl \ + software-properties-common \ + gpg-agent \ + && curl -fsSL https://download.docker.com/linux/debian/gpg | apt-key add - \ + && add-apt-repository "deb https://download.docker.com/linux/debian $(lsb_release -cs) stable" \ + && apt-get update && apt-get install -y --no-install-recommends \ + docker-ce \ + docker-ce-cli \ + containerd.io \ + && rm -rf /var/lib/apt/lists/* + +# Install shellcheck +RUN \ + curl -fLs \ + "https://github.com/koalaman/shellcheck/releases/download/stable/shellcheck-stable.linux.x86_64.tar.xz" \ + | tar -xJ \ + \ + && mv -f "./shellcheck-stable/shellcheck" "/usr/bin/shellcheck" \ + && rm -rf "./shellcheck-stable" + +# Generate a machine-id for this container +RUN rm /etc/machine-id && dbus-uuidgen --ensure=/etc/machine-id \ No newline at end of file diff --git a/oepl-proxy/.devcontainer/devcontainer.json b/oepl-proxy/.devcontainer/devcontainer.json new file mode 100644 index 0000000..8082a4d --- /dev/null +++ b/oepl-proxy/.devcontainer/devcontainer.json @@ -0,0 +1,18 @@ +{ + "name": "Home Assistant Add-Ons", + "context": "..", + "dockerFile": "Dockerfile", + "appPort": ["7123:8123", "7357:4357"], + "postStartCommand": "service docker start", + "runArgs": ["-e", "GIT_EDITOR=code --wait", "--privileged"], + "containerEnv": { + "WORKSPACE_DIRECTORY": "${containerWorkspaceFolder}" + }, + "extensions": [ + "timonwong.shellcheck", + "esbenp.prettier-vscode" + ], + "settings": { + "terminal.integrated.shell.linux": "/bin/bash" + } +} \ No newline at end of file diff --git a/oepl-proxy/.devcontainer/supervisor.sh b/oepl-proxy/.devcontainer/supervisor.sh new file mode 100755 index 0000000..d578370 --- /dev/null +++ b/oepl-proxy/.devcontainer/supervisor.sh @@ -0,0 +1,145 @@ +#!/bin/bash +set -eE + +SUPERVISOR_VERSON="$(curl -s https://version.home-assistant.io/stable.json | jq -e -r '.supervisor')" +DOCKER_TIMEOUT=30 +DOCKER_PID=0 + +function start_docker() { + local starttime + local endtime + + if grep -q 'Alpine|standard-WSL' /proc/version; then + # The docker daemon does not start when running WSL2 without adjusting iptables + update-alternatives --set iptables /usr/sbin/iptables-legacy || echo "Fails adjust iptables" + update-alternatives --set ip6tables /usr/sbin/iptables-legacy || echo "Fails adjust ip6tables" + fi + + echo "Starting docker." + dockerd 2> /dev/null & + DOCKER_PID=$! + + echo "Waiting for docker to initialize..." + starttime="$(date +%s)" + endtime="$(date +%s)" + until docker info >/dev/null 2>&1; do + if [ $((endtime - starttime)) -le $DOCKER_TIMEOUT ]; then + sleep 1 + endtime=$(date +%s) + else + echo "Timeout while waiting for docker to come up" + exit 1 + fi + done + echo "Docker was initialized" +} + +function stop_docker() { + local starttime + local endtime + + echo "Stopping in container docker..." + if [ "$DOCKER_PID" -gt 0 ] && kill -0 "$DOCKER_PID" 2> /dev/null; then + starttime="$(date +%s)" + endtime="$(date +%s)" + + # Now wait for it to die + kill "$DOCKER_PID" + while kill -0 "$DOCKER_PID" 2> /dev/null; do + if [ $((endtime - starttime)) -le $DOCKER_TIMEOUT ]; then + sleep 1 + endtime=$(date +%s) + else + echo "Timeout while waiting for container docker to die" + exit 1 + fi + done + else + echo "Your host might have been left with unreleased resources" + fi +} + + +function cleanup_lastboot() { + if [[ -f /tmp/supervisor_data/config.json ]]; then + echo "Cleaning up last boot" + cp /tmp/supervisor_data/config.json /tmp/config.json + jq -rM 'del(.last_boot)' /tmp/config.json > /tmp/supervisor_data/config.json + rm /tmp/config.json + fi +} + + +function cleanup_docker() { + echo "Cleaning up stopped containers..." + docker rm "$(docker ps -a -q)" || true +} + +function run_supervisor() { + mkdir -p /tmp/supervisor_data + docker run --rm --privileged \ + --name hassio_supervisor \ + --privileged \ + --security-opt seccomp=unconfined \ + --security-opt apparmor:unconfined \ + -v /run/docker.sock:/run/docker.sock:rw \ + -v /run/dbus:/run/dbus:ro \ + -v /run/udev:/run/udev:ro \ + -v /tmp/supervisor_data:/data:rw \ + -v "$WORKSPACE_DIRECTORY":/data/addons/local:rw \ + -v /etc/machine-id:/etc/machine-id:ro \ + -e SUPERVISOR_SHARE="/tmp/supervisor_data" \ + -e SUPERVISOR_NAME=hassio_supervisor \ + -e SUPERVISOR_DEV=1 \ + -e SUPERVISOR_MACHINE="qemux86-64" \ + "homeassistant/amd64-hassio-supervisor:${SUPERVISOR_VERSON}" +} + +function init_dbus() { + if pgrep dbus-daemon; then + echo "Dbus is running" + return 0 + fi + + echo "Startup dbus" + mkdir -p /var/lib/dbus + cp -f /etc/machine-id /var/lib/dbus/machine-id + + # cleanups + mkdir -p /run/dbus + rm -f /run/dbus/pid + + # run + dbus-daemon --system --print-address +} + +function init_udev() { + if pgrep systemd-udevd; then + echo "udev is running" + return 0 + fi + + echo "Startup udev" + + # cleanups + mkdir -p /run/udev + + # run + /lib/systemd/systemd-udevd --daemon + sleep 3 + udevadm trigger && udevadm settle +} + +echo "Start Test-Env" + +start_docker +trap "stop_docker" ERR + +docker system prune -f + +cleanup_lastboot +cleanup_docker +init_dbus +init_udev +run_supervisor +stop_docker \ No newline at end of file diff --git a/oepl-proxy/.gitattributes b/oepl-proxy/.gitattributes new file mode 100644 index 0000000..526c8a3 --- /dev/null +++ b/oepl-proxy/.gitattributes @@ -0,0 +1 @@ +*.sh text eol=lf \ No newline at end of file diff --git a/oepl-proxy/.vscode/tasks.json b/oepl-proxy/.vscode/tasks.json new file mode 100644 index 0000000..81384a1 --- /dev/null +++ b/oepl-proxy/.vscode/tasks.json @@ -0,0 +1,31 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Start Home Assistant", + "type": "shell", + "command": "./.devcontainer/supervisor.sh", + "group": { + "kind": "test", + "isDefault": true, + }, + "presentation": { + "reveal": "always", + "panel": "new" + }, + "problemMatcher": [] + },{ + "label": "Run Home Assistant CLI", + "type": "shell", + "command": "docker exec -ti hassio_cli /usr/bin/cli.sh", + "group": "test", + "presentation": { + "reveal": "always", + "panel": "new" + }, + "problemMatcher": [] + } + ] +} \ No newline at end of file diff --git a/oepl-proxy/CHANGELOG.md b/oepl-proxy/CHANGELOG.md new file mode 100644 index 0000000..a0b499e --- /dev/null +++ b/oepl-proxy/CHANGELOG.md @@ -0,0 +1,3 @@ +### 1.0 + +- Initial release diff --git a/oepl-proxy/DOCS.md b/oepl-proxy/DOCS.md new file mode 100644 index 0000000..84b92b0 --- /dev/null +++ b/oepl-proxy/DOCS.md @@ -0,0 +1,20 @@ +This addon creates a proxy to a OpenEpaperLink access point so that you can have the benefit of access in the sidebar without accessing the access point from the internet. + +## Configuration + +### Option: `server` + +The `server` option sets the address of the valetudo robot. + +This must be in the format `host:port`. The following are valid examples: + +- `oepl.local:80` +- `192.168.0.101:5000` + +## Required Dependencies + +- Network access to OEPL access point + +## Support + +There is no support diff --git a/oepl-proxy/Dockerfile b/oepl-proxy/Dockerfile new file mode 100644 index 0000000..e79610c --- /dev/null +++ b/oepl-proxy/Dockerfile @@ -0,0 +1,43 @@ +ARG BUILD_ARCH +# hadolint ignore=DL3006 +FROM ghcr.io/hassio-addons/debian-base/${BUILD_ARCH}:5.1.0 + +# Set shell +SHELL ["/bin/bash", "-o", "pipefail", "-c"] + +# Setup base +# hadolint ignore=DL3003 +RUN apt-get -qq update \ + && apt-get -qq install --no-install-recommends -y nginx \ + && (apt-get autoremove -y; apt-get autoclean -y) + +# Copy root filesystem +COPY rootfs / + +# Build arguments +ARG BUILD_ARCH +ARG BUILD_DATE +ARG BUILD_DESCRIPTION +ARG BUILD_NAME +ARG BUILD_REF +ARG BUILD_REPOSITORY +ARG BUILD_VERSION + +# Labels +LABEL \ + io.hass.name="${BUILD_NAME}" \ + io.hass.description="${BUILD_DESCRIPTION}" \ + io.hass.arch="${BUILD_ARCH}" \ + io.hass.type="addon" \ + io.hass.version=${BUILD_VERSION} \ + maintainer="jhbruhn " \ + org.opencontainers.image.title="${BUILD_NAME}" \ + org.opencontainers.image.description="${BUILD_DESCRIPTION}" \ + org.opencontainers.image.vendor="OEPL Proxy Add-on" \ + org.opencontainers.image.authors="jhbruhn " \ + org.opencontainers.image.licenses="MIT" \ + org.opencontainers.image.source="https://git.baubs.net/${BUILD_REPOSITORY}" \ + org.opencontainers.image.documentation="https://git.baubs.net/${BUILD_REPOSITORY}/blob/main/oepl-proxy/README.md" \ + org.opencontainers.image.created=${BUILD_DATE} \ + org.opencontainers.image.revision=${BUILD_REF} \ + org.opencontainers.image.version=${BUILD_VERSION} diff --git a/oepl-proxy/README.md b/oepl-proxy/README.md new file mode 100644 index 0000000..98b4a50 --- /dev/null +++ b/oepl-proxy/README.md @@ -0,0 +1,11 @@ +# Home Assistant Add-on: Valetudo Proxy + +![Supports aarch64 Architecture][aarch64-shield] ![Supports amd64 Architecture][amd64-shield] ![Supports armhf Architecture][armhf-shield] ![Supports armv7 Architecture][armv7-shield] ![Supports i386 Architecture][i386-shield] + +This addon creates a proxy to a Valetudo robot so that you can have the benefit of access in the sidebar without accessing the robot from the internet. + +[aarch64-shield]: https://img.shields.io/badge/aarch64-yes-green.svg +[amd64-shield]: https://img.shields.io/badge/amd64-yes-green.svg +[armhf-shield]: https://img.shields.io/badge/armhf-yes-green.svg +[armv7-shield]: https://img.shields.io/badge/armv7-yes-green.svg +[i386-shield]: https://img.shields.io/badge/i386-yes-green.svg diff --git a/oepl-proxy/config.yaml b/oepl-proxy/config.yaml new file mode 100644 index 0000000..02cf3e0 --- /dev/null +++ b/oepl-proxy/config.yaml @@ -0,0 +1,37 @@ +name: OEPL Proxy +version: "1.0" +panel_icon: "mdi:tag" +panel_title: OEPL +slug: oepl-proxy +description: Proxy addon for OpenEpaperLink +url: "https://git.baubs.net/jhbruhn/homeassistant-addons" +startup: application +boot: auto +webui: "http://[HOST]:[PORT:5000]/" +watchdog: "http://[HOST]:[PORT:5000]/" +ingress: true +ingress_port: 5000 +ingress_entry: / +panel_admin: false +ports: + 5000/tcp: 5000 +ports_description: + 5000/tcp: Web interface (Not required for Hass.io Ingress) +host_network: false +devices: [] +usb: false +tmpfs: false +full_access: false +environment: {} +options: + server: "192.168.0.123:80" +schema: + server: "match(^.+:\\d+$)" +services: [] +arch: + - aarch64 + - amd64 + - armhf + - armv7 + - i386 +map: [] diff --git a/oepl-proxy/icon.png b/oepl-proxy/icon.png new file mode 100644 index 0000000..e82d0c0 Binary files /dev/null and b/oepl-proxy/icon.png differ diff --git a/oepl-proxy/logo.png b/oepl-proxy/logo.png new file mode 100644 index 0000000..6f501f6 Binary files /dev/null and b/oepl-proxy/logo.png differ diff --git a/oepl-proxy/rootfs/etc/cont-init.d/nginx.sh b/oepl-proxy/rootfs/etc/cont-init.d/nginx.sh new file mode 100644 index 0000000..21ad794 --- /dev/null +++ b/oepl-proxy/rootfs/etc/cont-init.d/nginx.sh @@ -0,0 +1,18 @@ +#!/usr/bin/with-contenv bashio +# ============================================================================== +# Configures NGINX for use with this add-on. +# ============================================================================== +declare server + +bashio::var.json \ + entry "$(bashio::addon.ingress_entry)" \ + | tempio \ + -template /etc/nginx/templates/ingress.gtpl \ + -out /etc/nginx/servers/ingress.conf + +server=$(bashio::config 'server') + +echo '{"server":"'"$server"'"}' \ + | tempio \ + -template /etc/nginx/templates/upstream.gtpl \ + -out /etc/nginx/includes/upstream.conf diff --git a/oepl-proxy/rootfs/etc/nginx/includes/mime.types b/oepl-proxy/rootfs/etc/nginx/includes/mime.types new file mode 100644 index 0000000..7c7cdef --- /dev/null +++ b/oepl-proxy/rootfs/etc/nginx/includes/mime.types @@ -0,0 +1,96 @@ +types { + text/html html htm shtml; + text/css css; + text/xml xml; + image/gif gif; + image/jpeg jpeg jpg; + application/javascript js; + application/atom+xml atom; + application/rss+xml rss; + + text/mathml mml; + text/plain txt; + text/vnd.sun.j2me.app-descriptor jad; + text/vnd.wap.wml wml; + text/x-component htc; + + image/png png; + image/svg+xml svg svgz; + image/tiff tif tiff; + image/vnd.wap.wbmp wbmp; + image/webp webp; + image/x-icon ico; + image/x-jng jng; + image/x-ms-bmp bmp; + + font/woff woff; + font/woff2 woff2; + + application/java-archive jar war ear; + application/json json; + application/mac-binhex40 hqx; + application/msword doc; + application/pdf pdf; + application/postscript ps eps ai; + application/rtf rtf; + application/vnd.apple.mpegurl m3u8; + application/vnd.google-earth.kml+xml kml; + application/vnd.google-earth.kmz kmz; + application/vnd.ms-excel xls; + application/vnd.ms-fontobject eot; + application/vnd.ms-powerpoint ppt; + application/vnd.oasis.opendocument.graphics odg; + application/vnd.oasis.opendocument.presentation odp; + application/vnd.oasis.opendocument.spreadsheet ods; + application/vnd.oasis.opendocument.text odt; + application/vnd.openxmlformats-officedocument.presentationml.presentation + pptx; + application/vnd.openxmlformats-officedocument.spreadsheetml.sheet + xlsx; + application/vnd.openxmlformats-officedocument.wordprocessingml.document + docx; + application/vnd.wap.wmlc wmlc; + application/x-7z-compressed 7z; + application/x-cocoa cco; + application/x-java-archive-diff jardiff; + application/x-java-jnlp-file jnlp; + application/x-makeself run; + application/x-perl pl pm; + application/x-pilot prc pdb; + application/x-rar-compressed rar; + application/x-redhat-package-manager rpm; + application/x-sea sea; + application/x-shockwave-flash swf; + application/x-stuffit sit; + application/x-tcl tcl tk; + application/x-x509-ca-cert der pem crt; + application/x-xpinstall xpi; + application/xhtml+xml xhtml; + application/xspf+xml xspf; + application/zip zip; + + application/octet-stream bin exe dll; + application/octet-stream deb; + application/octet-stream dmg; + application/octet-stream iso img; + application/octet-stream msi msp msm; + + audio/midi mid midi kar; + audio/mpeg mp3; + audio/ogg ogg; + audio/x-m4a m4a; + audio/x-realaudio ra; + + video/3gpp 3gpp 3gp; + video/mp2t ts; + video/mp4 mp4; + video/mpeg mpeg mpg; + video/quicktime mov; + video/webm webm; + video/x-flv flv; + video/x-m4v m4v; + video/x-mng mng; + video/x-ms-asf asx asf; + video/x-ms-wmv wmv; + video/x-msvideo avi; +} diff --git a/oepl-proxy/rootfs/etc/nginx/includes/proxy_params.conf b/oepl-proxy/rootfs/etc/nginx/includes/proxy_params.conf new file mode 100644 index 0000000..327adb4 --- /dev/null +++ b/oepl-proxy/rootfs/etc/nginx/includes/proxy_params.conf @@ -0,0 +1,11 @@ +proxy_http_version 1.1; + +proxy_set_header Accept-Encoding ""; +proxy_set_header Connection $connection_upgrade; +proxy_set_header Host $http_host; +proxy_set_header Upgrade $http_upgrade; +proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; +proxy_set_header X-Forwarded-Proto $scheme; +proxy_set_header X-Real-IP $remote_addr; + + diff --git a/oepl-proxy/rootfs/etc/nginx/includes/server_params.conf b/oepl-proxy/rootfs/etc/nginx/includes/server_params.conf new file mode 100644 index 0000000..6bea037 --- /dev/null +++ b/oepl-proxy/rootfs/etc/nginx/includes/server_params.conf @@ -0,0 +1,6 @@ +root /dev/null; +server_name $hostname; + +#add_header X-Content-Type-Options nosniff; +#add_header X-XSS-Protection "1; mode=block"; +#add_header X-Robots-Tag none; diff --git a/oepl-proxy/rootfs/etc/nginx/includes/ssl_params.conf b/oepl-proxy/rootfs/etc/nginx/includes/ssl_params.conf new file mode 100644 index 0000000..e6789cb --- /dev/null +++ b/oepl-proxy/rootfs/etc/nginx/includes/ssl_params.conf @@ -0,0 +1,8 @@ +ssl_protocols TLSv1.2 TLSv1.3; +ssl_prefer_server_ciphers off; +ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; +ssl_session_timeout 10m; +ssl_session_cache shared:SSL:10m; +ssl_session_tickets off; +ssl_stapling on; +ssl_stapling_verify on; diff --git a/oepl-proxy/rootfs/etc/nginx/nginx.conf b/oepl-proxy/rootfs/etc/nginx/nginx.conf new file mode 100644 index 0000000..11e15c7 --- /dev/null +++ b/oepl-proxy/rootfs/etc/nginx/nginx.conf @@ -0,0 +1,44 @@ +# Run nginx in foreground. +daemon off; + +# This is run inside Docker. +user root; + +# Pid storage location. +pid /var/run/nginx.pid; + +# Set number of worker processes. +worker_processes 1; + +# Enables the use of JIT for regular expressions to speed-up their processing. +pcre_jit on; + +# Write error log to the add-on log. +error_log /proc/1/fd/1 error; + +# Max num of simultaneous connections by a worker process. +events { + worker_connections 512; +} + +http { + include /etc/nginx/includes/mime.types; + + access_log off; + client_max_body_size 4G; + default_type application/octet-stream; + gzip on; + keepalive_timeout 65; + sendfile on; + server_tokens off; + tcp_nodelay on; + tcp_nopush on; + + map $http_upgrade $connection_upgrade { + default upgrade; + '' close; + } + + include /etc/nginx/includes/upstream.conf; + include /etc/nginx/servers/*.conf; +} diff --git a/oepl-proxy/rootfs/etc/nginx/servers/.gitkeep b/oepl-proxy/rootfs/etc/nginx/servers/.gitkeep new file mode 100644 index 0000000..85ad51b --- /dev/null +++ b/oepl-proxy/rootfs/etc/nginx/servers/.gitkeep @@ -0,0 +1 @@ +Without requirements or design, programming is the art of adding bugs to an empty text file. (Louis Srygley) diff --git a/oepl-proxy/rootfs/etc/nginx/templates/ingress.gtpl b/oepl-proxy/rootfs/etc/nginx/templates/ingress.gtpl new file mode 100644 index 0000000..2380eaa --- /dev/null +++ b/oepl-proxy/rootfs/etc/nginx/templates/ingress.gtpl @@ -0,0 +1,14 @@ +server { + listen 5000 default_server; + + include /etc/nginx/includes/server_params.conf; + + location / { + allow 172.30.32.2; + deny all; + + proxy_pass http://backend/; + #proxy_set_header X-Ingress-Path {{ .entry }}; + include /etc/nginx/includes/proxy_params.conf; + } +} \ No newline at end of file diff --git a/oepl-proxy/rootfs/etc/nginx/templates/upstream.gtpl b/oepl-proxy/rootfs/etc/nginx/templates/upstream.gtpl new file mode 100644 index 0000000..873b90c --- /dev/null +++ b/oepl-proxy/rootfs/etc/nginx/templates/upstream.gtpl @@ -0,0 +1,3 @@ +upstream backend { + server {{ .server }}; +} diff --git a/oepl-proxy/rootfs/etc/services.d/nginx/finish b/oepl-proxy/rootfs/etc/services.d/nginx/finish new file mode 100644 index 0000000..a7cb83b --- /dev/null +++ b/oepl-proxy/rootfs/etc/services.d/nginx/finish @@ -0,0 +1,8 @@ +#!/usr/bin/execlineb -S0 +# ============================================================================== +# Take down the S6 supervision tree when Nginx fails +# ============================================================================== +if -n { s6-test $# -ne 0 } +if -n { s6-test ${1} -eq 256 } + +s6-svscanctl -t /var/run/s6/services diff --git a/oepl-proxy/rootfs/etc/services.d/nginx/run b/oepl-proxy/rootfs/etc/services.d/nginx/run new file mode 100644 index 0000000..3bf804a --- /dev/null +++ b/oepl-proxy/rootfs/etc/services.d/nginx/run @@ -0,0 +1,7 @@ +#!/usr/bin/with-contenv bashio +# ============================================================================== +# Runs the Nginx daemon +# ============================================================================== + +bashio::log.info "Starting NGinx..." +exec nginx