diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..afcee70 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,332 @@ +--- +image: docker:stable + +variables: + ADDON_GITHUB_REPO: hassio-addons/addon-sonweb + ADDON_SLUG: sonweb + ADDON_TARGET: sonweb + DOCKER_DRIVER: overlay2 + DOCKER_HUB_ORG: hassioaddons + +stages: + - preflight + - build + - scan + - deploy + - publish + +# Generic DIND template +.dind: &dind + before_script: + - docker info + - docker login -u gitlab-ci-token -p "${CI_JOB_TOKEN}" registry.gitlab.com + services: + - docker:dind + +# Generic preflight template +.preflight: &preflight + stage: preflight + tags: + - preflight + +# Generic build template +.build: &build + <<: *dind + stage: build + script: + - | + docker run \ + --privileged \ + --volume /var/run/docker.sock:/var/run/docker.sock \ + --volume "$PWD":/docker \ + hassioaddons/build-env:latest \ + --image "addon" \ + --cache-from "${DOCKER_HUB_ORG}/${ADDON_SLUG}-${ADDON_ARCH}" \ + --cache-tag "test" \ + --git-url "https://github.com/${ADDON_GITHUB_REPO}" \ + --target "${ADDON_TARGET}" \ + --tag-latest \ + --git \ + --${ADDON_ARCH} + - | + docker tag \ + "addon:latest" \ + "registry.gitlab.com/${CI_PROJECT_PATH}/${ADDON_ARCH}:${CI_COMMIT_SHA}" + - | + docker push \ + "registry.gitlab.com/${CI_PROJECT_PATH}/${ADDON_ARCH}:${CI_COMMIT_SHA}" + tags: + - build + +# Generic scan template +.scan: &scan + <<: *dind + stage: scan + allow_failure: true + before_script: + - docker info + - docker run -d --name db arminc/clair-db:latest + - docker run -p 6060:6060 --link db:postgres -d --name clair arminc/clair-local-scan:v2.0.1 + - apk add -U curl ca-certificates + - | + curl \ + --silent \ + --show-error \ + --location \ + --fail \ + --retry 3 \ + --output /usr/bin/clair-scanner \ + https://github.com/arminc/clair-scanner/releases/download/v8/clair-scanner_linux_amd64 + - chmod +x /usr/bin/clair-scanner + - touch clair-whitelist.yml + - echo "Waiting for Clair to start" + - | + while ! nc -z docker 6060; do + sleep 1 + WAIT=$((${WAIT} + 1)) + if [ "${WAIT}" -gt 30 ]; then + echo "Error > Timeout waiting for Clair to start" + exit 1 + fi + done + - docker pull "registry.gitlab.com/${CI_PROJECT_PATH}/${ADDON_ARCH}:${CI_COMMIT_SHA}" + script: + - | + clair-scanner \ + -c http://docker:6060 \ + --ip $(hostname -i) \ + -w clair-whitelist.yml \ + "registry.gitlab.com/${CI_PROJECT_PATH}/${ADDON_ARCH}:${CI_COMMIT_SHA}" + tags: + - scan + +# Generic deploy template +.deploy: &deploy + <<: *dind + stage: deploy + before_script: + - docker info + - docker login -u gitlab-ci-token -p "${CI_JOB_TOKEN}" registry.gitlab.com + - docker pull "registry.gitlab.com/${CI_PROJECT_PATH}/${ADDON_ARCH}:${CI_COMMIT_SHA}" + - docker pull hassioaddons/build-env:latest + script: + - | + docker run \ + --privileged \ + --volume /var/run/docker.sock:/var/run/docker.sock \ + --volume "$PWD":/docker \ + hassioaddons/build-env:latest \ + --image "${DOCKER_HUB_ORG}/${ADDON_SLUG}-${ADDON_ARCH}" \ + --cache-from "registry.gitlab.com/${CI_PROJECT_PATH}/${ADDON_ARCH}" \ + --cache-tag "${CI_COMMIT_SHA}" \ + --git-url "https://github.com/${ADDON_GITHUB_REPO}" \ + --target "${ADDON_TARGET}" \ + --login "${DOCKER_LOGIN}" \ + --password "${DOCKER_PASSWORD}" \ + --git \ + --push \ + --${ADDON_ARCH} + tags: + - deploy + +# Generic publish template +.publish: &publish + stage: publish + image: + name: hassioaddons/repository-updater:latest + entrypoint: [""] + script: + - | + repository-updater \ + --token "${GITHUB_TOKEN}" \ + --repository "${REPOSITORY}" \ + --addon "${ADDON_GITHUB_REPO}" + tags: + - publish + +# Preflight jobs +hadolint: + <<: *preflight + image: hadolint/hadolint:latest + before_script: + - hadolint --version + script: + - hadolint "${ADDON_TARGET}/Dockerfile" + +shellcheck: + <<: *preflight + image: + name: koalaman/shellcheck-alpine:stable + entrypoint: [""] + before_script: + - shellcheck --version + - apk --no-cache add grep + - | + find . -type f -print0 | \ + xargs -0 sed -i 's:#!/usr/bin/with-contenv bash:#!/bin/bash:g' + script: + - | + for file in $(grep -IRl "#\!\(/usr/bin/env \|/bin/\)" --exclude-dir ".git" "${ADDON_TARGET}"); do + if ! shellcheck $file; then + export FAILED=1 + else + echo "$file OK" + fi + done + if [ "${FAILED}" = "1" ]; then + exit 1 + fi + +yamllint: + <<: *preflight + image: sdesbure/yamllint + before_script: + - yamllint --version + script: + - yamllint . + +jsonlint: + <<: *preflight + image: sahsu/docker-jsonlint + before_script: + - jsonlint --version || true + script: + - | + for file in $(find . -type f -name "*.json"); do + if ! jsonlint -q $file; then + export FAILED=1 + else + echo "$file OK" + fi + done + if [ "${FAILED}" = "1" ]; then + exit 1 + fi + +markdownlint: + <<: *preflight + image: + name: ruby:alpine + entrypoint: [""] + before_script: + - gem install mdl + - mdl --version + script: + - mdl --style all --warnings . + +# Build jobs +build:armhf: + <<: *build + variables: + ADDON_ARCH: armhf + +build:aarch64: + <<: *build + variables: + ADDON_ARCH: aarch64 + +build:i386: + <<: *build + variables: + ADDON_ARCH: i386 + +build:amd64: + <<: *build + variables: + ADDON_ARCH: amd64 + +# Scan jobs +clair:armhf: + <<: *scan + variables: + ADDON_ARCH: armhf + +clair:aarch64: + <<: *scan + variables: + ADDON_ARCH: aarch64 + +clair:i386: + <<: *scan + variables: + ADDON_ARCH: i386 + +clair:amd64: + <<: *scan + variables: + ADDON_ARCH: amd64 + +# Deploy jobs +deploy:armhf: + <<: *deploy + variables: + ADDON_ARCH: armhf + only: + - master + - /^v\d+\.\d+\.\d+(?:-(?:beta|rc)(?:(?:(?:\+|\.)?[a-zA-Z0-9]+)*)?)?$/ + except: + - /^(?!master).+@/ + +deploy:aarch64: + <<: *deploy + variables: + ADDON_ARCH: aarch64 + only: + - master + - /^v\d+\.\d+\.\d+(?:-(?:beta|rc)(?:(?:(?:\+|\.)?[a-zA-Z0-9]+)*)?)?$/ + except: + - /^(?!master).+@/ + +deploy:i386: + <<: *deploy + variables: + ADDON_ARCH: i386 + only: + - master + - /^v\d+\.\d+\.\d+(?:-(?:beta|rc)(?:(?:(?:\+|\.)?[a-zA-Z0-9]+)*)?)?$/ + except: + - /^(?!master).+@/ + +deploy:amd64: + <<: *deploy + variables: + ADDON_ARCH: amd64 + only: + - master + - /^v\d+\.\d+\.\d+(?:-(?:beta|rc)(?:(?:(?:\+|\.)?[a-zA-Z0-9]+)*)?)?$/ + except: + - /^(?!master).+@/ + +# Publish jobs +stable: + <<: *publish + variables: + REPOSITORY: hassio-addons/repository + only: + - /^v\d+\.\d+\.\d+(?:(?:(?:\+|\.)?[a-zA-Z0-9]+)*)?$/ + except: + - /^(?!master).+@/ + environment: + name: stable + +beta: + <<: *publish + variables: + REPOSITORY: hassio-addons/repository-beta + only: + - /^v\d+\.\d+\.\d+(?:-(?:beta|rc)(?:(?:(?:\+|\.)?[a-zA-Z0-9]+)*)?)?$/ + except: + - /^(?!master).+@/ + environment: + name: beta + +edge: + <<: *publish + variables: + REPOSITORY: hassio-addons/repository-edge + only: + - master + except: + - /^(?!master).+@/ + environment: + name: edge diff --git a/README.md b/README.md new file mode 100755 index 0000000..716b13b --- /dev/null +++ b/README.md @@ -0,0 +1,272 @@ +# Community Hass.io Add-ons: SonWEB + +[![GitHub Release][releases-shield]][releases] +![Project Stage][project-stage-shield] +[![License][license-shield]](LICENSE.md) + +[![GitLab CI][gitlabci-shield]][gitlabci] +![Project Maintenance][maintenance-shield] +[![GitHub Activity][commits-shield]][commits] + +[![Bountysource][bountysource-shield]][bountysource] +[![Discord][discord-shield]][discord] +[![Community Forum][forum-shield]][forum] + +[![Buy me a coffee][buymeacoffee-shield]][buymeacoffee] + +Centrally manage all your Sonoff-Tasmota devices. + +![SonWEB screenshot](images/screenshot.png) + +## About + +SonWEB is an administrative web interface to manage all your Sonoff-Tasmota +flashed devices centrally. Some of its features: + +- Scans your networks and adds your devices automatically +- See the status off all your devices quick and easy +- Configure all your devices from a single place +- Send out firmware updates over the air to one or more your devices at once +- Can automatically download the latest firmware for you + +## Installation + +The installation of this add-on is pretty straightforward and not different in +comparison to installing any other Hass.io add-on. + +1. [Add our Hass.io add-ons repository][repository] to your Hass.io instance. +1. Install the "SonWEB" add-on +1. Start the "SonWEB" add-on +1. Check the logs of the "SonWEB" if everything went well + +**NOTE**: Do not add this repository to Hass.io, please use: +`https://github.com/hassio-addons/repository`. + +## Docker status + +[![Docker Architecture][armhf-arch-shield]][armhf-dockerhub] +[![Docker Version][armhf-version-shield]][armhf-microbadger] +[![Docker Layers][armhf-layers-shield]][armhf-microbadger] +[![Docker Pulls][armhf-pulls-shield]][armhf-dockerhub] + +[![Docker Architecture][aarch64-arch-shield]][aarch64-dockerhub] +[![Docker Version][aarch64-version-shield]][aarch64-microbadger] +[![Docker Layers][aarch64-layers-shield]][aarch64-microbadger] +[![Docker Pulls][aarch64-pulls-shield]][aarch64-dockerhub] + +[![Docker Architecture][amd64-arch-shield]][amd64-dockerhub] +[![Docker Version][amd64-version-shield]][amd64-microbadger] +[![Docker Layers][amd64-layers-shield]][amd64-microbadger] +[![Docker Pulls][amd64-pulls-shield]][amd64-dockerhub] + +[![Docker Architecture][i386-arch-shield]][i386-dockerhub] +[![Docker Version][i386-version-shield]][i386-microbadger] +[![Docker Layers][i386-layers-shield]][i386-microbadger] +[![Docker Pulls][i386-pulls-shield]][i386-dockerhub] + +## Configuration + +**Note**: _Remember to restart the add-on when the configuration is changed._ + +Example add-on configuration: + +```json +{ + "log_level": "info", + "ssl": false, + "certfile": "fullchain.pem", + "keyfile": "privkey.pem", + "ipv6": true +} +``` + +**Note**: _This is just an example, don't copy and past it! Create your own!_ + +### Option: `log_level` + +The `log_level` option controls the level of log output by the addon and can +be changed to be more or less verbose, which might be useful when you are +dealing with an unknown issue. Possible values are: + +- `trace`: Show every detail, like all called internal functions. +- `debug`: Shows detailed debug information. +- `info`: Normal (usually) interesting events. +- `warning`: Exceptional occurrences that are not errors. +- `error`: Runtime errors that do not require immediate action. +- `fatal`: Something went terribly wrong. Add-on becomes unusable. + +Please note that each level automatically includes log messages from a +more severe level, e.g., `debug` also shows `info` messages. By default, +the `log_level` is set to `info`, which is the recommended setting unless +you are troubleshooting. + +### Option: `ssl` + +Enables/Disables SSL (HTTPS) on the web interface of SonWEB +Panel. Set it `true` to enable it, `false` otherwise. + +### Option: `certfile` + +The certificate file to use for SSL. + +**Note**: _The file MUST be stored in `/ssl/`, which is the default for Hass.io_ + +### Option: `keyfile` + +The private key file to use for SSL. + +**Note**: _The file MUST be stored in `/ssl/`, which is the default for Hass.io_ + +### Option: `ipv6` + +Set this option too `false` to disable IPv6 support. + +## Embedding into Home Assistant + +It is possible to embed the SonWEB interface directly into Home Assistant, +allowing you to access it through the Home Assistant frontend. + +Home Assistant provides the `panel_iframe` component, for these purposes. + +Example configuration: + +```yaml +panel_iframe: + sonweb: + title: SonWEB + icon: mdi:light-switch + url: http://addres.to.your.hass.io:9541 +``` + +## Changelog & Releases + +This repository keeps a change log using [GitHub's releases][releases] +functionality. The format of the log is based on +[Keep a Changelog][keepchangelog]. + +Releases are based on [Semantic Versioning][semver], and use the format +of ``MAJOR.MINOR.PATCH``. In a nutshell, the version will be incremented +based on the following: + +- ``MAJOR``: Incompatible or major changes. +- ``MINOR``: Backwards-compatible new features and enhancements. +- ``PATCH``: Backwards-compatible bugfixes and package updates. + +## Support + +Got questions? + +You have several options to get them answered: + +- The Home Assistant [Community Forum][forum], we have a + [dedicated topic][forum] on that forum regarding this add-on. +- The Home Assistant [Discord Chat Server][discord] for general Home Assistant + discussions and questions. +- Join the [Reddit subreddit][reddit] in [/r/homeassistant][reddit] + +You could also [open an issue here][issue] GitHub. + +## Contributing + +This is an active open-source project. We are always open to people who want to +use the code or contribute to it. + +We have set up a separate document containing our +[contribution guidelines](CONTRIBUTING.md). + +Thank you for being involved! :heart_eyes: + +## Authors & contributors + +The original setup of this repository is by [Franck Nijhof][frenck]. + +For a full list of all authors and contributors, +check [the contributor's page][contributors]. + +## We have got some Hass.io add-ons for you + +Want some more functionality to your Hass.io Home Assistant instance? + +We have created multiple add-ons for Hass.io. For a full list, check out +our [GitHub Repository][repository]. + +## License + +MIT License + +Copyright (c) 2018 Franck Nijhof + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +[aarch64-anchore-shield]: https://anchore.io/service/badges/image/db1960b51d33fe80c8a6f3318f327532c3a7f1f501c767dfa3d9202196982e2f +[aarch64-anchore]: https://anchore.io/image/dockerhub/hassioaddons%2Fsonweb-aarch64%3Alatest +[aarch64-arch-shield]: https://img.shields.io/badge/architecture-aarch64-blue.svg +[aarch64-dockerhub]: https://hub.docker.com/r/hassioaddons/sonweb-aarch64 +[aarch64-layers-shield]: https://images.microbadger.com/badges/image/hassioaddons/sonweb-aarch64.svg +[aarch64-microbadger]: https://microbadger.com/images/hassioaddons/sonweb-aarch64 +[aarch64-pulls-shield]: https://img.shields.io/docker/pulls/hassioaddons/sonweb-aarch64.svg +[aarch64-version-shield]: https://images.microbadger.com/badges/version/hassioaddons/sonweb-aarch64.svg +[amd64-anchore-shield]: https://anchore.io/service/badges/image/67ef5b927a8e861eee9e576477f4f6f1e52ccc30c657e906720a8fa3a9fe5fc7 +[amd64-anchore]: https://anchore.io/image/dockerhub/hassioaddons%2Fsonweb-amd64%3Alatest +[amd64-arch-shield]: https://img.shields.io/badge/architecture-amd64-blue.svg +[amd64-dockerhub]: https://hub.docker.com/r/hassioaddons/sonweb-amd64 +[amd64-layers-shield]: https://images.microbadger.com/badges/image/hassioaddons/sonweb-amd64.svg +[amd64-microbadger]: https://microbadger.com/images/hassioaddons/sonweb-amd64 +[amd64-pulls-shield]: https://img.shields.io/docker/pulls/hassioaddons/sonweb-amd64.svg +[amd64-version-shield]: https://images.microbadger.com/badges/version/hassioaddons/sonweb-amd64.svg +[armhf-anchore-shield]: https://anchore.io/service/badges/image/f2968fbefd4a99acfd25c100c099fcc1a5ae486289ca5b3548efde4c02583cc4 +[armhf-anchore]: https://anchore.io/image/dockerhub/hassioaddons%2Fsonweb-armhf%3Alatest +[armhf-arch-shield]: https://img.shields.io/badge/architecture-armhf-blue.svg +[armhf-dockerhub]: https://hub.docker.com/r/hassioaddons/sonweb-armhf +[armhf-layers-shield]: https://images.microbadger.com/badges/image/hassioaddons/sonweb-armhf.svg +[armhf-microbadger]: https://microbadger.com/images/hassioaddons/sonweb-armhf +[armhf-pulls-shield]: https://img.shields.io/docker/pulls/hassioaddons/sonweb-armhf.svg +[armhf-version-shield]: https://images.microbadger.com/badges/version/hassioaddons/sonweb-armhf.svg +[bountysource-shield]: https://img.shields.io/bountysource/team/hassio-addons/activity.svg +[bountysource]: https://www.bountysource.com/teams/hassio-addons/issues +[buymeacoffee-shield]: https://www.buymeacoffee.com/assets/img/guidelines/download-assets-sm-2.svg +[buymeacoffee]: https://www.buymeacoffee.com/frenck +[commits-shield]: https://img.shields.io/github/commit-activity/y/hassio-addons/addon-sonweb.svg +[commits]: https://github.com/hassio-addons/addon-sonweb/commits/master +[contributors]: https://github.com/hassio-addons/addon-sonweb/graphs/contributors +[discord-shield]: https://img.shields.io/discord/330944238910963714.svg +[discord]: https://discord.gg/c5DvZ4e +[forum-shield]: https://img.shields.io/badge/community-forum-brightgreen.svg +[forum]: https://community.home-assistant.io/?u=frenck +[frenck]: https://github.com/frenck +[gitlabci-shield]: https://gitlab.com/hassio-addons/addon-sonweb/badges/master/pipeline.svg +[gitlabci]: https://gitlab.com/hassio-addons/addon-sonweb/pipelines +[i386-anchore-shield]: https://anchore.io/service/badges/image/bfa0ec04d5a8519ccfaf3be75bcd92bd1d9821946e39368d2b88d7d14d16e58e +[i386-anchore]: https://anchore.io/image/dockerhub/hassioaddons%2Fsonweb-i386%3Alatest +[i386-arch-shield]: https://img.shields.io/badge/architecture-i386-blue.svg +[i386-dockerhub]: https://hub.docker.com/r/hassioaddons/sonweb-i386 +[i386-layers-shield]: https://images.microbadger.com/badges/image/hassioaddons/sonweb-i386.svg +[i386-microbadger]: https://microbadger.com/images/hassioaddons/sonweb-i386 +[i386-pulls-shield]: https://img.shields.io/docker/pulls/hassioaddons/sonweb-i386.svg +[i386-version-shield]: https://images.microbadger.com/badges/version/hassioaddons/sonweb-i386.svg +[issue]: https://github.com/hassio-addons/addon-sonweb/issues +[keepchangelog]: http://keepachangelog.com/en/1.0.0/ +[license-shield]: https://img.shields.io/github/license/hassio-addons/addon-sonweb.svg +[maintenance-shield]: https://img.shields.io/maintenance/yes/2018.svg +[project-stage-shield]: https://img.shields.io/badge/project%20stage-concept-red.svg +[reddit]: https://reddit.com/r/homeassistant +[releases-shield]: https://img.shields.io/github/release/hassio-addons/addon-sonweb.svg +[releases]: https://github.com/hassio-addons/addon-sonweb/releases +[repository]: https://github.com/hassio-addons/repository +[semver]: http://semver.org/spec/v2.0.0.html diff --git a/images/screenshot.png b/images/screenshot.png new file mode 100644 index 0000000..19e9e86 Binary files /dev/null and b/images/screenshot.png differ diff --git a/sonweb/.README.j2 b/sonweb/.README.j2 new file mode 100644 index 0000000..936686b --- /dev/null +++ b/sonweb/.README.j2 @@ -0,0 +1,76 @@ +# Community Hass.io Add-ons: SonWEB + +[![Release][release-shield]][release] ![Project Stage][project-stage-shield] ![Project Maintenance][maintenance-shield] + +[![Discord][discord-shield]][discord] [![Community Forum][forum-shield]][forum] + +[![Buy me a coffee][buymeacoffee-shield]][buymeacoffee] + +Centrally manage all your Sonoff-Tasmota devices. + +## About + +SonWEB is an administrative web interface to manage all your Sonoff-Tasmota +flashed devices centrally. Some of its features: + +- Scans your networks and adds your devices automatically +- See the status off all your devices quick and easy +- Configure all your devices from a single place +- Send out firmware updates over the air to one or more your devices at once +- Can automatically download the latest firmware for you + +[Click here for the full documentation][docs] + +![SonWEB screenshot][screenshot] + +{% if channel == "edge" %} +## WARNING! THIS IS AN EDGE VERSION! + +This Hass.io Add-ons repository contains edge builds of add-ons. Edge builds +add-ons are based upon the latest development version. + +- They may not work at all. +- They might stop working at any time. +- They could have a negative impact on your system. + +This repository was created for: + +- Anybody willing to test. +- Anybody interested in trying out upcoming add-ons or add-on features. +- Developers. + +If you are more interested in stable releases of our add-ons: + + + +{% endif %} +{% if channel == "beta" %} +## WARNING! THIS IS A BETA VERSION! + +This Hass.io Add-ons repository contains beta releases of add-ons. + +- They might stop working at any time. +- They could have a negative impact on your system. + +This repository was created for: + +- Anybody willing to test. +- Anybody interested in trying out upcoming add-ons or add-on features. + +If you are more interested in stable releases of our add-ons: + + + +{% endif %} +[buymeacoffee-shield]: https://www.buymeacoffee.com/assets/img/guidelines/download-assets-sm-2.svg +[buymeacoffee]: https://www.buymeacoffee.com/frenck +[discord-shield]: https://img.shields.io/discord/330944238910963714.svg +[discord]: https://discord.gg/c5DvZ4e +[docs]: {{ repo }}/blob/{{ version }}/README.md +[forum-shield]: https://img.shields.io/badge/community-forum-brightgreen.svg +[forum]: https://community.home-assistant.io/?u=frenck +[maintenance-shield]: https://img.shields.io/maintenance/yes/2018.svg +[project-stage-shield]: https://img.shields.io/badge/project%20stage-concept-red.svg +[release-shield]: https://img.shields.io/badge/version-{{ version }}-blue.svg +[release]: {{ repo }}/tree/{{ version }} +[screenshot]: https://github.com/hassio-addons/addon-sonweb/raw/master/images/screenshot.png diff --git a/sonweb/Dockerfile b/sonweb/Dockerfile new file mode 100755 index 0000000..734f2fd --- /dev/null +++ b/sonweb/Dockerfile @@ -0,0 +1,58 @@ +ARG BUILD_FROM=hassioaddons/base-amd64:1.4.1 +# hadolint ignore=DL3006 +FROM ${BUILD_FROM} + +# Setup base +RUN \ + apk add --no-cache \ + nginx=1.12.2-r3 \ + patch=2.7.5-r2 \ + php7-curl=7.1.17-r0 \ + php7-fpm=7.1.17-r0 \ + php7-json=7.1.17-r0 \ + php7-opcache=7.1.17-r0 \ + php7-session=7.1.17-r0 \ + php7-zip=7.1.17-r0 \ + php7=7.1.17-r0 \ + \ + && apk add --no-cache --virtual .build-dependencies \ + git=2.15.0-r1 \ + \ + && git clone --branch master --single-branch \ + https://github.com/reloxx13/SonWEB.git /var/www/sonweb \ + && git -C /var/www/sonweb checkout 74704ba33f7b4df0d5fd75c55253356edbb65029 \ + \ + && apk del --purge .build-dependencies \ + \ + && rm -f -r /var/www/sonweb/.git \ + && find /var/www/sonweb -type f -name ".htaccess" -depth -exec rm -f {} \; \ + && find /var/www/sonweb -type f -name "*.md" -depth -exec rm -f {} \; \ + && find /var/www/sonweb -type f -name ".gitignore" -depth -exec rm -f {} \; \ + && find /var/www/sonweb -type f -name ".empty" -depth -exec rm -f {} \; + +# Copy root filesystem +COPY rootfs / + +# Build arugments +ARG BUILD_ARCH +ARG BUILD_DATE +ARG BUILD_REF +ARG BUILD_VERSION + +# Labels +LABEL \ + io.hass.name="SonWEB" \ + io.hass.description="Centrally manage all your Sonoff-Tasmota devices" \ + io.hass.arch="${BUILD_ARCH}" \ + io.hass.type="addon" \ + io.hass.version=${BUILD_VERSION} \ + maintainer="Franck Nijhof " \ + org.label-schema.description="Centrally manage all your Sonoff-Tasmota devices" \ + org.label-schema.build-date=${BUILD_DATE} \ + org.label-schema.name="SonWEB" \ + org.label-schema.schema-version="1.0" \ + org.label-schema.url="https://community.home-assistant.io/?u=frenck" \ + org.label-schema.usage="https://github.com/hassio-addons/addon-sonweb/tree/master/README.md" \ + org.label-schema.vcs-ref=${BUILD_REF} \ + org.label-schema.vcs-url="https://github.com/hassio-addons/addon-sonweb" \ + org.label-schema.vendor="Community Hass.io Addons" diff --git a/sonweb/build.json b/sonweb/build.json new file mode 100755 index 0000000..17647ee --- /dev/null +++ b/sonweb/build.json @@ -0,0 +1,10 @@ +{ + "squash": false, + "build_from": { + "aarch64": "hassioaddons/base-aarch64:1.4.1", + "amd64": "hassioaddons/base-amd64:1.4.1", + "armhf": "hassioaddons/base-armhf:1.4.1", + "i386": "hassioaddons/base-i386:1.4.1" + }, + "args": {} +} diff --git a/sonweb/config.json b/sonweb/config.json new file mode 100755 index 0000000..a2f6bfd --- /dev/null +++ b/sonweb/config.json @@ -0,0 +1,40 @@ +{ + "name": "SonWEB", + "version": "dev", + "slug": "sonweb", + "description": "Centrally manage all your Sonoff-Tasmota devices", + "url": "https://community.home-assistant.io/?u=frenck", + "webui": "[PROTO:ssl]://[HOST]:[PORT:9541]", + "startup": "system", + "arch": [ + "aarch64", + "amd64", + "armhf", + "i386" + ], + "boot": "auto", + "hassio_api": true, + "map": [ + "ssl" + ], + "ports": { + "9541/tcp": 9541 + }, + "options": { + "log_level": "info", + "ssl": false, + "certfile": "fullchain.pem", + "keyfile": "privkey.pem", + "ipv6": false + }, + "schema": { + "log_level": "match(^(trace|debug|info|notice|warning|error|fatal)$)", + "ssl": "bool", + "certfile": "str", + "keyfile": "str", + "ipv6": "bool" + }, + "environment": { + "LOG_FORMAT": "{LEVEL}: {MESSAGE}" + } +} diff --git a/sonweb/icon.png b/sonweb/icon.png new file mode 100755 index 0000000..ce94a95 Binary files /dev/null and b/sonweb/icon.png differ diff --git a/sonweb/logo.png b/sonweb/logo.png new file mode 100755 index 0000000..1b7526a Binary files /dev/null and b/sonweb/logo.png differ diff --git a/sonweb/rootfs/etc/cont-init.d/10-requirements.sh b/sonweb/rootfs/etc/cont-init.d/10-requirements.sh new file mode 100755 index 0000000..c4b0b3a --- /dev/null +++ b/sonweb/rootfs/etc/cont-init.d/10-requirements.sh @@ -0,0 +1,26 @@ +#!/usr/bin/with-contenv bash +# ============================================================================== +# Community Hass.io Add-ons: SonWEB +# This files check if all user configuration requirements are met +# ============================================================================== +# shellcheck disable=SC1091 +source /usr/lib/hassio-addons/base.sh + +# Check SSL requirements, if enabled +if hass.config.true 'ssl'; then + if ! hass.config.has_value 'certfile'; then + hass.die 'SSL is enabled, but no certfile was specified' + fi + + if ! hass.config.has_value 'keyfile'; then + hass.die 'SSL is enabled, but no keyfile was specified' + fi + + if ! hass.file_exists "/ssl/$(hass.config.get 'certfile')"; then + hass.die 'The configured certfile is not found' + fi + + if ! hass.file_exists "/ssl/$(hass.config.get 'keyfile')"; then + hass.die 'The configured keyfile is not found' + fi +fi diff --git a/sonweb/rootfs/etc/cont-init.d/11-nginx.sh b/sonweb/rootfs/etc/cont-init.d/11-nginx.sh new file mode 100755 index 0000000..fd3b383 --- /dev/null +++ b/sonweb/rootfs/etc/cont-init.d/11-nginx.sh @@ -0,0 +1,25 @@ +#!/usr/bin/with-contenv bash +# ============================================================================== +# Community Hass.io Add-ons: SonWEB +# Configures NGINX for use with SonWEB +# ============================================================================== +# shellcheck disable=SC1091 +source /usr/lib/hassio-addons/base.sh + +declare certfile +declare keyfile + +if hass.config.true 'ssl'; then + rm /etc/nginx/nginx.conf + mv /etc/nginx/nginx-ssl.conf /etc/nginx/nginx.conf + + certfile=$(hass.config.get 'certfile') + keyfile=$(hass.config.get 'keyfile') + + sed -i "s/%%certfile%%/${certfile}/g" /etc/nginx/nginx.conf + sed -i "s/%%keyfile%%/${keyfile}/g" /etc/nginx/nginx.conf +fi + +if ! hass.config.true 'ipv6'; then + sed -i '/listen \[::\].*/ d' /etc/nginx/nginx.conf +fi diff --git a/sonweb/rootfs/etc/cont-init.d/12-patches.sh b/sonweb/rootfs/etc/cont-init.d/12-patches.sh new file mode 100644 index 0000000..cd476a5 --- /dev/null +++ b/sonweb/rootfs/etc/cont-init.d/12-patches.sh @@ -0,0 +1,36 @@ +#!/usr/bin/with-contenv bash +# ============================================================================== +# Community Hass.io Add-ons: SonWEB +# Applies patch to remove SelfUpdate, since that is useless shit in Docker +# ============================================================================== +# shellcheck disable=SC1091 +source /usr/lib/hassio-addons/base.sh + +patch -F2 -R --ignore-whitespace /var/www/sonweb/includes/header.php <<'PATCH' +--- header.php 2018-05-22 00:00:00.463304792 +0200 ++++ header.php 2018-05-22 00:00:00.291634513 +0200 +@@ -178,6 +178,15 @@ + + + ++ ++ ++ ++ + + + +PATCH + +# shellcheck disable=SC2181 +if [[ "$?" -ne 0 ]]; +then + hass.die 'Patching SonWEB SelfUpdate failed' +fi + +hass.log.debug 'Applied SonWEB SelfUpdate fix' diff --git a/sonweb/rootfs/etc/cont-init.d/13-persistent-data.sh b/sonweb/rootfs/etc/cont-init.d/13-persistent-data.sh new file mode 100644 index 0000000..c514e51 --- /dev/null +++ b/sonweb/rootfs/etc/cont-init.d/13-persistent-data.sh @@ -0,0 +1,23 @@ +#!/usr/bin/with-contenv bash +# ============================================================================== +# Community Hass.io Add-ons: SonWEB +# Ensures data is store in a persistent location +# ============================================================================== +# shellcheck disable=SC1091 +source /usr/lib/hassio-addons/base.sh + +if ! hass.directory_exists "/data/sonweb"; then + hass.log.debug 'Data directory not initialized, doing that now...' + + # Setup structure + cp -R /var/www/sonweb/data /data/sonweb + + # Ensure file permissions + chown -R nginx:nginx /data/sonweb + find /data/sonweb -not -perm 0644 -type f -exec chmod 0644 {} \; + find /data/sonweb -not -perm 0755 -type d -exec chmod 0755 {} \; +fi + +hass.log.debug 'Symlinking data directory to persistent storage location...' +rm -f -r /var/www/sonweb/data +ln -s /data/sonweb /var/www/sonweb/data diff --git a/sonweb/rootfs/etc/fix-attrs.d/01-sonweb b/sonweb/rootfs/etc/fix-attrs.d/01-sonweb new file mode 100644 index 0000000..8da210a --- /dev/null +++ b/sonweb/rootfs/etc/fix-attrs.d/01-sonweb @@ -0,0 +1,2 @@ +/var/www/sonweb true nginx 0644 0755 +/data/sonweb true nginx 0644 0755 diff --git a/sonweb/rootfs/etc/nginx/nginx-ssl.conf b/sonweb/rootfs/etc/nginx/nginx-ssl.conf new file mode 100755 index 0000000..fa28992 --- /dev/null +++ b/sonweb/rootfs/etc/nginx/nginx-ssl.conf @@ -0,0 +1,62 @@ +worker_processes 1; +pid /var/run/nginx.pid; +user nginx nginx; + +events { + worker_connections 1024; +} + +http { + include mime.types; + default_type application/octet-stream; + sendfile on; + keepalive_timeout 65; + + server { + server_name hassio.local; + listen 9541 default_server ssl; + listen [::]:9541 default_server ssl; + root /var/www/sonweb; + index index.php; + + ssl_certificate /ssl/%%certfile%%; + ssl_certificate_key /ssl/%%keyfile%%; + ssl_protocols TLSv1.2; + ssl_prefer_server_ciphers on; + ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:DHE-RSA-AES256-SHA; + ssl_ecdh_curve secp384r1; + ssl_session_timeout 10m; + ssl_session_cache shared:SSL:10m; + ssl_session_tickets off; + ssl_stapling on; + ssl_stapling_verify on; + + add_header X-Content-Type-Options nosniff; + add_header X-XSS-Protection "1; mode=block"; + add_header X-Robots-Tag none; + + location ~ .php$ { + fastcgi_pass 127.0.0.1:9001; + fastcgi_read_timeout 900; + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + include fastcgi_params; + } + + location /data/ { + deny all; + } + + rewrite ^/login$ /login.php last; + rewrite ^/logout$ /login.php?logout=logout last; + rewrite ^/doAjaxAll$ /index.php?doAjaxAll=doAjaxAll last; + rewrite ^/doAjax$ /index.php?doAjax=doAjax last; + rewrite "/([a-z]{2})/" /index.php?lang=$1 last; + rewrite ^/([a-zA-Z_]+)/([a-zA-Z_]+)/([0-9_]+)/?$ /index.php?page=$1&action=$2&device_id=$3; + rewrite ^/([a-zA-Z_]+)/(force)/?$ /index.php?page=$1&force=1; + rewrite ^/([a-zA-Z_]+)/([a-zA-Z_]+)/?$ /index.php?page=$1&action=$2; + rewrite ^/([a-zA-Z_]+)/([0-9]+)/?$ /index.php?page=$1&device_id=$2; + rewrite ^/([a-zA-Z_]+)/?$ /index.php?page=$1; + } +} diff --git a/sonweb/rootfs/etc/nginx/nginx.conf b/sonweb/rootfs/etc/nginx/nginx.conf new file mode 100755 index 0000000..c1a8d7d --- /dev/null +++ b/sonweb/rootfs/etc/nginx/nginx.conf @@ -0,0 +1,46 @@ +worker_processes 1; +pid /var/run/nginx.pid; +user nginx nginx; + +events { + worker_connections 1024; +} + +http { + include mime.types; + default_type application/octet-stream; + sendfile on; + keepalive_timeout 65; + + server { + server_name hassio.local; + listen 9541 default_server; + listen [::]:9541 default_server; + root /var/www/sonweb/; + index index.php; + + location ~ .php$ { + fastcgi_pass 127.0.0.1:9001; + fastcgi_read_timeout 900; + fastcgi_split_path_info ^(.+\.php)(/.+)$; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + include fastcgi_params; + } + + location /data/ { + deny all; + } + + rewrite ^/login$ /login.php last; + rewrite ^/logout$ /login.php?logout=logout last; + rewrite ^/doAjaxAll$ /index.php?doAjaxAll=doAjaxAll last; + rewrite ^/doAjax$ /index.php?doAjax=doAjax last; + rewrite "/([a-z]{2})/" /index.php?lang=$1 last; + rewrite ^/([a-zA-Z_]+)/([a-zA-Z_]+)/([0-9_]+)/?$ /index.php?page=$1&action=$2&device_id=$3; + rewrite ^/([a-zA-Z_]+)/(force)/?$ /index.php?page=$1&force=1; + rewrite ^/([a-zA-Z_]+)/([a-zA-Z_]+)/?$ /index.php?page=$1&action=$2; + rewrite ^/([a-zA-Z_]+)/([0-9]+)/?$ /index.php?page=$1&device_id=$2; + rewrite ^/([a-zA-Z_]+)/?$ /index.php?page=$1; + } +} diff --git a/sonweb/rootfs/etc/php7/blacklist.txt b/sonweb/rootfs/etc/php7/blacklist.txt new file mode 100644 index 0000000..f47d41f --- /dev/null +++ b/sonweb/rootfs/etc/php7/blacklist.txt @@ -0,0 +1,2 @@ +/data/sonweb/* +/var/www/sonweb/data/* diff --git a/sonweb/rootfs/etc/php7/conf.d/99-sonweb.ini b/sonweb/rootfs/etc/php7/conf.d/99-sonweb.ini new file mode 100644 index 0000000..82d2f7c --- /dev/null +++ b/sonweb/rootfs/etc/php7/conf.d/99-sonweb.ini @@ -0,0 +1,9 @@ +[general] +max_execution_time = 900 +opcache.enable=1 +opcache.interned_strings_buffer=8 +opcache.max_accelerated_files=4096 +opcache.memory_consumption=32 +opcache.revalidate_freq=0 +opcache.validate_timestamps=0 +opcache.blacklist_filename=/etc/php7/blacklist.txt diff --git a/sonweb/rootfs/etc/php7/php-fpm.d/www.conf b/sonweb/rootfs/etc/php7/php-fpm.d/www.conf new file mode 100644 index 0000000..13c8a71 --- /dev/null +++ b/sonweb/rootfs/etc/php7/php-fpm.d/www.conf @@ -0,0 +1,11 @@ +[www] +user = nginx +group = nginx +listen = 127.0.0.1:9001 +pm = dynamic +pm.max_children = 10 +pm.start_servers = 3 +pm.min_spare_servers = 2 +pm.max_spare_servers = 5 +pm.max_requests = 1024 +clear_env = yes diff --git a/sonweb/rootfs/etc/services.d/nginx/finish b/sonweb/rootfs/etc/services.d/nginx/finish new file mode 100755 index 0000000..b8068ed --- /dev/null +++ b/sonweb/rootfs/etc/services.d/nginx/finish @@ -0,0 +1,9 @@ +#!/usr/bin/execlineb -S0 +# ============================================================================== +# Community Hass.io Add-ons: SonWEB +# 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/sonweb/rootfs/etc/services.d/nginx/run b/sonweb/rootfs/etc/services.d/nginx/run new file mode 100755 index 0000000..4e3702b --- /dev/null +++ b/sonweb/rootfs/etc/services.d/nginx/run @@ -0,0 +1,12 @@ +#!/usr/bin/with-contenv bash +# ============================================================================== +# Community Hass.io Add-ons: SonWEB +# Runs the Nginx daemon +# ============================================================================== +# shellcheck disable=SC1091 +source /usr/lib/hassio-addons/base.sh + +# Wait for PHP-FPM to become available +s6-svwait -u -t 5000 /var/run/s6/services/php-fpm + +exec nginx -g "daemon off;" diff --git a/sonweb/rootfs/etc/services.d/php-fpm/finish b/sonweb/rootfs/etc/services.d/php-fpm/finish new file mode 100644 index 0000000..b84521c --- /dev/null +++ b/sonweb/rootfs/etc/services.d/php-fpm/finish @@ -0,0 +1,9 @@ +#!/usr/bin/execlineb -S0 +# ============================================================================== +# Community Hass.io Add-ons: SonWEB +# Take down the S6 supervision tree when PHP FPM fails +# ============================================================================== +if -n { s6-test $# -ne 0 } +if -n { s6-test ${1} -eq 256 } + +s6-svscanctl -t /var/run/s6/services diff --git a/sonweb/rootfs/etc/services.d/php-fpm/run b/sonweb/rootfs/etc/services.d/php-fpm/run new file mode 100644 index 0000000..7486cc0 --- /dev/null +++ b/sonweb/rootfs/etc/services.d/php-fpm/run @@ -0,0 +1,9 @@ +#!/usr/bin/with-contenv bash +# ============================================================================== +# Community Hass.io Add-ons: SonWEB +# Runs the PHP-FPM daemon +# ============================================================================== +# shellcheck disable=SC1091 +source /usr/lib/hassio-addons/base.sh + +exec php-fpm7 --nodaemonize