This commit is contained in:
2024-06-17 17:34:06 +02:00
parent da23315ab9
commit 97b4e2d7b1
409 changed files with 4274 additions and 15396 deletions

View File

@@ -0,0 +1,28 @@
{
"name": "Example devcontainer for add-on repositories",
"image": "ghcr.io/home-assistant/devcontainer:addons",
"appPort": ["7123:8123", "7357:4357"],
"postStartCommand": "sudo -E bash devcontainer_bootstrap",
"runArgs": ["-e", "GIT_EDITOR=code --wait", "--privileged"],
"containerEnv": {
"WORKSPACE_DIRECTORY": "${containerWorkspaceFolder}"
},
"customizations": {
"vscode": {
"extensions": ["timonwong.shellcheck", "esbenp.prettier-vscode"],
"settings": {
"terminal.integrated.profiles.linux": {
"zsh": {
"path": "/usr/bin/zsh"
}
},
"terminal.integrated.defaultProfile.linux": "zsh",
"editor.formatOnPaste": false,
"editor.formatOnSave": true,
"editor.formatOnType": true,
"files.trimTrailingWhitespace": true
}
}
},
"mounts": [ "type=volume,target=/var/lib/docker" ]
}

6
.github/.gitattributes vendored Normal file
View File

@@ -0,0 +1,6 @@
# Set the default behavior, in case people don't have core.autocrlf set.
* text eol=lf
# Denote all files that are truly binary and should not be modified.
*.png binary
*.jpg binary

9
.github/.gitignore vendored Normal file
View File

@@ -0,0 +1,9 @@
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
!.vscode/*.code-snippets
# Local History for Visual Studio Code
.history/

1
.github/CODEOWNERS vendored
View File

@@ -1 +0,0 @@
.github/* @frenck

View File

@@ -1,133 +0,0 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
- Demonstrating empathy and kindness toward other people
- Being respectful of differing opinions, viewpoints, and experiences
- Giving and gracefully accepting constructive feedback
- Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
- Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
- The use of sexualized language or imagery, and sexual attention or
advances of any kind
- Trolling, insulting or derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or email
address, without their explicit permission
- Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
frenck@frenck.dev.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
[https://www.contributor-covenant.org/version/2/0/code_of_conduct.html][v2.0].
Community Impact Guidelines were inspired by
[Mozilla's code of conduct enforcement ladder][mozilla coc].
For answers to common questions about this code of conduct, see the FAQ at
[https://www.contributor-covenant.org/faq][faq]. Translations are available
at [https://www.contributor-covenant.org/translations][translations].
[homepage]: https://www.contributor-covenant.org
[v2.0]: https://www.contributor-covenant.org/version/2/0/code_of_conduct.html
[mozilla coc]: https://github.com/mozilla/diversity
[faq]: https://www.contributor-covenant.org/faq
[translations]: https://www.contributor-covenant.org/translations

View File

@@ -1,29 +0,0 @@
# Contributing
When contributing to this repository, please first discuss the change you wish
to make via issue, email, or any other method with the owners of this repository
before making a change.
Please note we have a code of conduct, please follow it in all your interactions
with the project.
## Issues and feature requests
You've found a bug in the source code, a mistake in the documentation or maybe
you'd like a new feature? You can help us by submitting an issue to our
[GitHub Repository][github]. Before you create an issue, make sure you search
the archive, maybe your question was already answered.
Even better: You could submit a pull request with a fix / new feature!
## Pull request process
1. Search our repository for open or closed [pull requests][prs] that relates
to your submission. You don't want to duplicate effort.
1. You may merge the pull request in once you have the sign-off of two other
developers, or if you do not have permission to do that, you may request
the second reviewer to merge it for you.
[github]: https://github.com/hassio-addons/repository/issues
[prs]: https://github.com/hassio-addons/repository/pulls

2
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,2 @@
---
custom: https://buymeacoffee.com/mesteriisw

View File

@@ -1,20 +0,0 @@
# Problem/Motivation
> (Why the issue was filed)
## Expected behavior
> (What you expected to happen)
## Actual behavior
> (What actually happened)
## Steps to reproduce
> (How can someone else make/see it happen)
## Proposed changes
> (If you have a proposed change, workaround or fix,
> describe the rationale behind it)

60
.github/ISSUE_TEMPLATE/BUG-REPORT.yml vendored Normal file
View File

@@ -0,0 +1,60 @@
---
name: "🐛 Bug Report"
description: Create a new ticket for a bug.
title: "🐛 [Addon name] <title>"
labels: [
"bug"
]
body:
- type: textarea
id: description
attributes:
label: "Description"
description: Please enter an explicit description of your issue
placeholder: Short and explicit description of your incident...
validations:
required: true
- type: textarea
id: reprod
attributes:
label: "Reproduction steps"
description: Please enter an explicit description of your issue
value: |
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
render: bash
validations:
required: true
- type: textarea
id: logs
attributes:
label: "Addon Logs"
description: Please paste the full log that appears when starting the addon (including banner). This will be automatically formatted into code, so no need for backticks.
render: bash
validations:
required: true
- type: dropdown
id: browsers
attributes:
label: "Architecture"
description: What architecture are you on ?
multiple: true
options:
- aarch64
- amd64
- armv7
validations:
required: false
- type: dropdown
id: os
attributes:
label: "OS"
description: What is the impacted environment ?
multiple: true
options:
- HAos
- Virtual Machine
validations:
required: false

2
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@@ -0,0 +1,2 @@
---
blank_issues_enabled: false

View File

@@ -0,0 +1,44 @@
---
name: "✨ Feature request"
description: Suggest an idea for this project
title: "✨ [REQUEST] Addon name"
labels: [
"prevent stale",
"enhancement"
]
body:
- type: markdown
attributes:
value: |
I have a real life job in parallel to this addon, and don't think I'll be able to add new addons for the moment. You can still however express your interest in case someone would do it.
- type: checkboxes
id: terms
attributes:
label: Checked
description: "Pre-checks"
options:
- label: "If a new addon, I have checked on Google that such as addon doesn't already exists"
required: true
- label: "If a new feature, I have searched in the discussions & issues that it was not already covered"
required: true
- type: textarea
id: description
attributes:
label: "Which addon?"
description: The title of the addon the new feature is for
validations:
required: true
- type: textarea
id: description2
attributes:
label: "Is your feature request related to a problem? Please describe"
description: A clear and concise description of what the problem is. Ex. I'm always frustrated when
validations:
required: true
- type: textarea
id: description3
attributes:
label: "Describe the solution you'd like"
description: A clear and concise description of what you want to happen
validations:
required: true

View File

@@ -0,0 +1,41 @@
---
name: "\u2753 Any other question"
about: Other questions or remarks not related to bugs or features
title: "\u2753 [addon] title"
labels: ['prevent stale']
assignees: ""
---
<!-- markdownlint-disable MD036 -->
**Which addon?**
<!--The title of the addon the new feature is for.-->
name: Feature request
about: Suggest an idea for this project
title: ''
labels: ''
assignees: ''
---
**Which addon?**
<!--The title of the addon the new feature is for.-->
**Addon or app?**
<!--Are you sure it is linked to the addon? If in the original app, the question should be posed there.-->
**Describe the solution you'd like**
<!--A clear and concise description of what you want to happen.-->
**Describe alternatives you've considered**
<!--A clear and concise description of any alternative solutions or features you've considered.-->
**Additional context**
<!--Add any other context here.-->

View File

@@ -1,9 +0,0 @@
# Proposed Changes
> (Describe the changes and rationale behind them)
## Related Issues
> ([Github link][autolink-references] to related issues or pull requests)
[autolink-references]: https://help.github.com/articles/autolinked-references-and-urls/

1839
.github/SECURITY.md vendored

File diff suppressed because it is too large Load Diff

View File

@@ -1,13 +0,0 @@
---
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: daily
time: "06:00"
- package-ecosystem: "pip"
directory: "/"
schedule:
interval: daily
time: "06:00"

10
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,10 @@
---
version: 2
updates:
# Maintain dependencies for GitHub Actions
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
labels:
- "dependency-update"

85
.github/labels.yml vendored
View File

@@ -1,85 +0,0 @@
---
- name: "breaking-change"
color: ee0701
description: "A breaking change for existing users."
- name: "bugfix"
color: ee0701
description: "Inconsistencies or issues which will cause a problem for users or implementors."
- name: "documentation"
color: 0052cc
description: "Solely about the documentation of the project."
- name: "enhancement"
color: 1d76db
description: "Enhancement of the code, not introducing new features."
- name: "refactor"
color: 1d76db
description: "Improvement of existing code, not introducing new features."
- name: "performance"
color: 1d76db
description: "Improving performance, not introducing new features."
- name: "new-feature"
color: 0e8a16
description: "New features or options."
- name: "maintenance"
color: 2af79e
description: "Generic maintenance tasks."
- name: "ci"
color: 1d76db
description: "Work that improves the continue integration."
- name: "dependencies"
color: 1d76db
description: "Upgrade or downgrade of project dependencies."
- name: "in-progress"
color: fbca04
description: "Issue is currently being resolved by a developer."
- name: "stale"
color: fef2c0
description: "There has not been activity on this issue or PR for quite some time."
- name: "no-stale"
color: fef2c0
description: "This issue or PR is exempted from the stable bot."
- name: "security"
color: ee0701
description: "Marks a security issue that needs to be resolved asap."
- name: "incomplete"
color: fef2c0
description: "Marks a PR or issue that is missing information."
- name: "invalid"
color: fef2c0
description: "Marks a PR or issue that is missing information."
- name: "beginner-friendly"
color: 0e8a16
description: "Good first issue for people wanting to contribute to the project."
- name: "help-wanted"
color: 0e8a16
description: "We need some extra helping hands or expertise in order to resolve this."
- name: "hacktoberfest"
description: "Issues/PRs are participating in the Hacktoberfest."
color: fbca04
- name: "hacktoberfest-accepted"
description: "Issues/PRs are participating in the Hacktoberfest."
color: fbca04
- name: "priority-critical"
color: ee0701
description: "This should be dealt with ASAP. Not fixing this issue would be a serious error."
- name: "priority-high"
color: b60205
description: "After critical issues are fixed, these should be dealt with before any further issues."
- name: "priority-medium"
color: 0e8a16
description: "This issue may be useful, and needs some attention."
- name: "priority-low"
color: e4ea8a
description: "Nice addition, maybe... someday..."
- name: "major"
color: b60205
description: "This PR causes a major version bump in the version number."
- name: "minor"
color: 0e8a16
description: "This PR causes a minor version bump in the version number."

10
.github/linters/.gitleaks.toml vendored Normal file
View File

@@ -0,0 +1,10 @@
title = "gitleaks config"
[extend]
# useDefault will extend the base configuration with the default gitleaks config:
# https://github.com/zricethezav/gitleaks/blob/master/config/gitleaks.toml
useDefault = false
[allowlist]
description = "global allowlist. whitelisting paths"
#paths = ['''/github/workspace/epicgamesfree/templates/config.json''']

8
.github/linters/.hadolint.yaml vendored Normal file
View File

@@ -0,0 +1,8 @@
---
ignored:
- DL3002
- DL3006
- DL3007
- DL3008
- DL3009
- DL3018

9
.github/linters/.jscpd.json vendored Normal file
View File

@@ -0,0 +1,9 @@
{
"threshold": 0,
"reporters": ["html", "markdown"],
"ignore": [
"**/.git/**",
"**/*.md",
"**/.github/**"
]
}

35
.github/linters/.markdown-lint.yml vendored Normal file
View File

@@ -0,0 +1,35 @@
---
###########################
###########################
## Markdown Linter rules ##
###########################
###########################
# Linter rules doc:
# - https://github.com/DavidAnson/markdownlint
#
# Note:
# To comment out a single error:
# <!-- markdownlint-disable -->
# any violations you want
# <!-- markdownlint-restore -->
#
###############
# Rules by id #
###############
MD001: false # Heading levels should only increment by one level at a time
MD002: false # First header should be a h1 header
MD007: # Unordered list indentation
indent: 2
MD012: false # Multiple consecutive blank lines
MD013: false # Line length
MD025: false # Multiple top level headings in the same document
MD034: false # Bare url
MD041: false # First line in file should be a top level header
MD053: false # Check links are used
#################
# Rules by tags #
#################
blank_lines: false # Error on blank lines

109
.github/paths-filter.yml vendored Normal file
View File

@@ -0,0 +1,109 @@
# AUTO BUILDS #
# From https://github.com/Poeschl/Hassio-Addons
# name: slug/filename ; could be slug/config.* for all files
addons_updater: addons_updater/config.* # Image : yes
arpspoof: arpspoof/config.* # Image : yes
autobrr: autobrr/config.* # Image : yes
baikal: baikal/config.* # Image : yes
bazarr: bazarr/config.* # Image : yes
binance-trading-bot: binance-trading-bot/config.* # Image : yes
birdnet-go: birdnet-go/config.* # Image : yes
birdnet-pi: birdnet-pi/config.* # Image : yes
bitwarden: bitwarden/config.* # Image : yes
booksonic_air: booksonic_air/config.* # Image : yes
browserless_chrome: browserless_chrome/config.* # Image : yes
calibre: calibre/config.* # Image : yes
calibre_web: calibre_web/config.* # Image : yes
changedetection.io: changedetection.io/config.* # Image : yes
cloudcommander: cloudcommander/config.* # Image : yes
code-server: code-server/config.* # Image : yes
codex: codex/config.* # Image : yes
comixed: comixed/config.* # Image : yes
elasticsearch: elasticsearch/config.* # Image : yes
emby: emby/config.* # Image : yes
enedisgateway2mqtt: enedisgateway2mqtt/config.* # Image : yes
enedisgateway2mqtt_dev: enedisgateway2mqtt_dev/config.* # Image : yes
epicgamesfree: epicgamesfree/config.* # Image : yes
filebrowser: filebrowser/config.* # Image : yes
fireflyiii: fireflyiii/config.* # Image : yes
fireflyiii_data_importer: fireflyiii_data_importer/config.* # Image : yes
fireflyiii_fints_importer: fireflyiii_fints_importer/config.* # Image : yes
flaresolverr: flaresolverr/config.* # Image : yes
flexget: flexget/config.* # Image : yes
free_games_claimer: free_games_claimer/config.* # Image : yes
gazpar2mqtt: gazpar2mqtt/config.* # Image : yes
gitea: gitea/config.* # Image : yes
grav: grav/config.* # Image : yes
guacamole: guacamole/config.* # Image : yes
immich: immich/config.* # Image : yes
immich_ingress: immich_ingress/config.* # Image : yes
inadyn: inadyn/config.* # Image : yes
jackett: jackett/config.* # Image : yes
jellyfin: jellyfin/config.* # Image : yes
jellyseerr: jellyseerr/config.* # Image : yes
joal: joal/config.* # Image : yes
joplin: joplin/config.* # Image : yes
lidarr: lidarr/config.* # Image : yes
linkwarden: linkwarden/config.* # Image : yes
mealie: mealie/config.* # Image : yes
mealie_api: mealie_api/config.* # Image : yes
mealie_frontend: mealie_frontend/config.* # IImage : yes # Image : yes
myelectricaldata: myelectricaldata/config.* # Image : yes
myelectricaldata_dev: myelectricaldata_dev/config.* # Image : yes
mylar3: mylar3/config.* # Image : yes
navidrome: navidrome/config.* # Image : yes
nextcloud: nextcloud/config.* # Image : yes
nzbget: nzbget/config.* # Image : yes
omada: omada/config.* # Image : yes
omada_v3: omada_v3/config.* # Image : yes
ombi: ombi/config.* # Image : yes
openproject: openproject/config.* # Image : yes
organizr: organizr/config.* # Image : yes
overleaf: overleaf/config.* # Image : yes
overseerr: overseerr/config.* # Image : yes
paperless_ngx: paperless_ngx/config.* # Image : yes
papermerge: papermerge/config.* # Image : yes
photoprism: photoprism/config.* # Image : yes
piwigo: piwigo/config.* # Image : yes
plex: plex/config.* # Image : yes
plex_meta_manager: plex_meta_manager/config.* # Image : yes
portainer: portainer/config.* # Image : yes
portainer_agent: portainer_agent/config.* # Image : yes
postgres: postgres/config.* # Image : yes
prowlarr: prowlarr/config.* # Image : yes
qbittorrent: qbittorrent/config.* # Image : yes
radarr: radarr/config.* # Image : yes
readarr: readarr/config.* # Image : yes
requestrr: requestrr/config.* # Image : yes
resiliosync: resiliosync/config.* # Image : yes
sabnzb: sabnzb/config.* # Image : yes
sabnzbd: sabnzbd/config.* # Image : yes
scrutiny: scrutiny/config.* # Image : yes
scrutiny_fa: scrutiny_fa/config.* # Image : yes
seafile: seafile/config.* # Image : yes
signalk: signalk/config.* # Image : yes
socks5-proxy: socks5-proxy/config.* # Image : yes
sonarr: sonarr/config.* # Image : yes
sponsorblockcast: sponsorblockcast/config.* # Image : yes
spotweb: spotweb/config.* # Image : yes
tandoor_recipes: tandoor_recipes/config.* # Image : yes
tdarr: tdarr/config.* # Image : yes
teamspeak: teamspeak/config.* # Image : yes
transmission: transmission/config.* # Image : yes
transmission_openvpn: transmission_openvpn/config.* # Image : yes
ubooquity: ubooquity/config.* # Image : yes
unpackerr: unpackerr/config.* # Image : yes
vaultwarden: vaultwarden/config.* # Image : yes
webtop: webtop/config.*
webtop_kde: webtop_kde/config.* # Image : yes
webtrees: webtrees/config.* # Image : yes
wger: wger/config.* # Image : yes
whatsapper: whatsapper/config.* # Image : yes
whoogle: whoogle/config.* # Image : yes
xteve: xteve/config.* # Image : yes
zoneminder: zoneminder/config.* # Image : yes
zzz_archived_bitwarden: zzz_archived_bitwarden/config.* # Image : yes
zzz_archived_code-server: zzz_archived_code-server/config.* # Image : yes
zzz_archived_paperless_ngx: zzz_archived_paperless_ngx/config.* # Image : yes
zzz_draft_birdnet-pi: zzz_draft_birdnet-pi/config.* # Image : yes
zzz_draft_overleaf: zzz_draft_overleaf/config.* # Image : yes

View File

@@ -0,0 +1,65 @@
---
name: Lint / Syntax checks
on:
push:
branches: [master]
pull_request:
branches: [master]
jobs:
hadolint:
runs-on: ubuntu-latest
container: ghcr.io/hadolint/hadolint:latest-alpine
steps:
- name: ↩️ Checkout
uses: actions/checkout@v4
- name: Get changed files
id: changed_files
uses: jitterbit/get-changed-files@v1
- name: 🔎 Run hadolint
run: |
# shellcheck disable=SC2043
for files in ${{ steps.changed_files.outputs.all }}; do
if [[ "$(basename ${files})" == "Dockerfile" ]]; then
echo "Hadolint $files"
hadolint "$files"
fi
done
shellcheck:
runs-on: ubuntu-latest
container: koalaman/shellcheck-alpine:latest
steps:
- name: ↩️ Checkout
uses: actions/checkout@v4
- name: Get changed files
id: changed_files
uses: jitterbit/get-changed-files@v1
- name: 🔎 Run ShellCheck
run: |
# shellcheck disable=SC2043
for files in ${{ steps.changed_files.outputs.all }}; do
if [[ "$files" == *".sh" ]]; then
echo "Spellcheck $files"
shellcheck "$files"
fi
done
markdownlint:
runs-on: ubuntu-latest
steps:
- name: ↩️ Checkout
uses: actions/checkout@v4
with:
# Full git history is needed to get a proper list of changed files within `super-linter`
fetch-depth: 0
- name: 🔎 Run markdownlint
uses: nosborn/github-action-markdown-cli@v3.3.0
with:
config_file: .markdownlint.yaml

157
.github/workflows/daily_README.yaml vendored Normal file
View File

@@ -0,0 +1,157 @@
# yamllint disable rule:line-length
---
name: Generate README
on:
schedule:
- cron: 0 17 * * *
workflow_dispatch: null
jobs:
README_updater:
runs-on: ubuntu-20.04
steps:
- name: Checkout Repo
uses: actions/checkout@v4
- name: Create README file
run: |
# Init
echo "Starting"
# Prepare template
cp .templates/.README.md README2.md
ADDONSLINE="$(sed -n '/%%ADDONS_LIST%%/=' README2.md)"
sed -i "/**ADDONS_LIST%%/d" README2.md
# Sort folders by addon name
# shellcheck disable=SC2086
for f in $( find -- * -maxdepth 0 -type d | sort -r ); do
if [ -f "$f"/config.json ]; then
NAME=$(jq -r '.name' "$f"/config.json)
if [[ "$f" != "$NAME" ]]; then
echo "$f" > "$f"/oldname
mv "$f" "$NAME"
fi
fi
done
# Populate template
find -- * -maxdepth 0 -type d | sort -r | while read -r f; do
# $f is an addon directory
if [ -f "$f/config.json" ]; then
echo "Project $f"
# Get variables
if [ -f "$f/oldname" ]; then FOLDERNAME="$(cat "$f/oldname")"; else FOLDERNAME="$f"; fi
NAME="$(jq -r '.name' "$f/config.json")"
DESCRIPTION="$(jq -r '.description' "$f/config.json")"
# Get icon
if [ "$(jq '.panel_icon' "$f/config.json")" != null ]; then
ICON="$(jq -r '.panel_icon' "$f/config.json")"
ICON="${ICON#*:}"
ICON="![image](https://api.iconify.design/mdi/$ICON.svg)"
else
ICON=""
fi
# Write infos
echo "Writing infos"
sed -i "$ADDONSLINE"'{G;}' README2.md
if [[ "$(jq '.schema' "$f/config.json" 2>/dev/null)" == *"localdisks"* ]]; then sed -i "$ADDONSLINE"'a ![localdisks][localdisks-badge]' README2.md; fi
if [[ "$(jq '.schema' "$f/config.json" 2>/dev/null)" == *"networkdisks"* ]]; then sed -i "$ADDONSLINE"'a ![smb][smb-badge]' README2.md; fi
if [[ "$(jq '.full_access' "$f/config.json" 2>/dev/null)" == "true" ]]; then sed -i "$ADDONSLINE"'a ![full_access][full_access-badge]' README2.md; fi
if [[ "$(jq '.services[]' "$f/config.json" 2>/dev/null)" == *"mqtt"* ]]; then sed -i "$ADDONSLINE"'a ![mqtt][mqtt-badge]' README2.md; fi
if [[ "$(jq '.services[]' "$f/config.json" 2>/dev/null)" == *"mysql"* ]]; then sed -i "$ADDONSLINE"'a ![MariaDB][mariadb-badge]' README2.md; fi
if [[ "$(jq '.ingress' "$f/config.json" 2>/dev/null)" == "true" ]]; then sed -i "$ADDONSLINE"'a ![ingress][ingress-badge]' README2.md; fi
if [[ "$(jq '.arch[]' "$f/config.json")" == *"armv7"* ]]; then
sed -i "$ADDONSLINE"'a ![armv7][armv7-badge]' README2.md
else sed -i "$ADDONSLINE"'a ![armv7no][armv7no-badge]' README2.md; fi || true
if [[ "$(jq '.arch[]' "$f/config.json")" == *"amd64"* ]]; then
sed -i "$ADDONSLINE"'a ![amd64][amd64-badge]' README2.md
else sed -i "$ADDONSLINE"'a ![amd64no][amd64no-badge]' README2.md; fi || true
if [[ "$(jq '.arch[]' "$f/config.json")" == *"aarch64"* ]]; then
sed -i "$ADDONSLINE"'a ![aarch64][aarch64-badge]' README2.md
else sed -i "$ADDONSLINE"'a ![aarch64no][aarch64no-badge]' README2.md; fi || true
if [[ -f "$f/updater.json" ]]; then sed -i "$ADDONSLINE"'a ![Update](https://img.shields.io/badge/dynamic/json?label=Updated&query=%24.last_update&url=https%3A%2F%2Fraw.githubusercontent.com%2Falexbelgium%2Fhassio-addons%2Fmaster%2F'"$FOLDERNAME"'%2Fupdater.json)' README2.md; fi
sed -i "$ADDONSLINE"'a &emsp;&emsp;![Version](https://img.shields.io/badge/dynamic/json?label=Version&query=%24.version&url=https%3A%2F%2Fraw.githubusercontent.com%2Falexbelgium%2Fhassio-addons%2Fmaster%2F'"$FOLDERNAME"'%2Fconfig.json)' README2.md || true
sed -i "$ADDONSLINE"'a &#10003; '"$ICON"' ['"$NAME"']('"$FOLDERNAME"'/) : '"$DESCRIPTION\\n" README2.md
fi
done
# Restore folders name
echo "Restore structure..."
find -- * -maxdepth 0 -type d | sort -r | while read -r f; do
if [ -f "$f/oldname" ]; then
NAME="$(cat "$f/oldname")"
rm "$f/oldname"
mv "$f" "$NAME"
fi
done
echo "... done"
# Write stats
# shellcheck disable=SC2002
echo "Global stats..."
STATS_DOWNLOADS="$(awk 'NR==2{print $1}' Stats)"
sed -i "s|%%STATS_DOWNLOADS%%|$STATS_DOWNLOADS|g" README2.md && \
sed -i "s|%%STATS_ADDONS%%|$(find . -name "config.json" | wc -l)|g" README2.md && \
STATS_ONE="$(awk 'NR==3{print $(NF)}' Stats)" && \
STATS_TWO="$(awk 'NR==4{print $(NF)}' Stats)" && \
STATS_THREE="$(awk 'NR==5{print $(NF)}' Stats)"
echo "Best addon is $STATS_ONE"
sed -i "s|%%STATS_ONE%%|${STATS_ONE^}|g" README2.md
sed -i "s|%%STATS_TWO%%|${STATS_TWO^}|g" README2.md
sed -i "s|%%STATS_THREE%%|${STATS_THREE^}|g" README2.md
echo "... done"
# Breakdown per arch
echo "Breakdown per arch..."
STATS_ARMV7="$(awk '{SUM+=$3}END{print SUM}' Stats2)"
STATS_AMD64="$(awk '{SUM+=$4}END{print SUM}' Stats2)"
STATS_AARCH64="$(awk '{SUM+=$5}END{print SUM}' Stats2)"
STATS_DOWNLOADS="$(( "$STATS_ARMV7" + "$STATS_AMD64" + "$STATS_AARCH64" ))"
STATS_ARMV7="$(awk -v t1="$STATS_ARMV7" -v t2="$STATS_AMD64" -v t3="$STATS_AARCH64" -v t4="$STATS_DOWNLOADS" 'BEGIN{printf "%.0f", t1/t4 * 100}')"
STATS_AMD64="$(awk -v t1="$STATS_ARMV7" -v t2="$STATS_AMD64" -v t3="$STATS_AARCH64" -v t4="$STATS_DOWNLOADS" 'BEGIN{printf "%.0f", t2/t4 * 100}')"
STATS_AARCH64="$(awk -v t1="$STATS_ARMV7" -v t2="$STATS_AMD64" -v t3="$STATS_AARCH64" -v t4="$STATS_DOWNLOADS" 'BEGIN{printf "%.0f", t3/t4 * 100}')"
sed -i "s|%%STATS_ARMV7%%|armv7: ${STATS_ARMV7}%|g" README2.md
sed -i "s|%%STATS_AMD64%%|amd64: ${STATS_AMD64}%|g" README2.md
sed -i "s|%%STATS_AARCH64%%|aarch64: ${STATS_AARCH64}%|g" README2.md
#echo $((100*$STATS_THREE/($STATS_ONE+$STATS_TWO+$STATS_THREE)))
echo "... done"
for var in "$STATS_ONE" "$STATS_TWO" "$STATS_THREE"; do
i=0
j=0
k=0
# shellcheck disable=SC2013
for i in $(sed -n "/$var/p" Stats); do
k="$((k+1))"
if [ "$k" -eq 3 ]; then break; fi
if [ "$i" -eq "$i" ] && [ "$i" -gt "$j" ]; then j="$i"; fi
done
sed -i "s|${var^}|${var^} (${j}x)|g" README2.md
echo "$STATS_ONE has $j downloads"
done
echo "... done"
# Replace template if change
echo "Replace template..."
mv README2.md README.md
echo "... done"
shell: bash
- name: Commit if needed
uses: EndBug/add-and-commit@v9
with:
message: "GitHub bot : README updated"
default_author: github_actions

33
.github/workflows/daily_stale.yml vendored Normal file
View File

@@ -0,0 +1,33 @@
# This workflow warns and then closes issues and PRs
# that have had no activity for a specified amount of time.
#
# You can adjust the behavior by modifying this file.
# For more information, see:
# https://github.com/actions/stale
---
name: Mark stale issues and pull requests
on:
schedule:
- cron: '0 12 * * *'
workflow_dispatch:
jobs:
stale:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- uses: actions/stale@v8
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
stale-issue-message: 'This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.'
stale-pr-message: 'Stale pull request message'
stale-issue-label: 'stale'
stale-pr-label: 'stale'
days-before-stale: '5'
days-before-close: '2'
exempt-issue-labels: 'prevent stale'
remove-stale-when-updated: true

View File

@@ -0,0 +1,242 @@
# yamllint disable rule:line-length
---
name: Generate weekly graphs
on:
workflow_call:
workflow_dispatch:
jobs:
stats_graphs:
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@v4
- name: Install apps
run: |
git pull --rebase origin master
sudo apt-get update
sudo apt-get install gnuplot -y || true
- name: Create addons stats
run: |
# Prepare data
cp Stats Stats3
# Remove Totals
sed -i "2d" Stats3
# Inverse file
gawk -i inplace '{for(i=NF;i>1;i--)printf "%s ",$i;printf "%s",$1;print ""}' Stats3
# Only top 10
head -n 11 Stats3 > tmp_file && mv tmp_file Stats3
# Transpose data
awk '
{
for (i=1; i<=NF; i++) {
a[NR,i] = $i
}
}
NF>p { p = NF }
END {
for(j=1; j<=p; j++) {
str=a[1,j]
for(i=2; i<=NR; i++){
str=str" "a[i,j];
}
print str
}
}' Stats3 > StatsTmp && mv StatsTmp .github/Stats3
cd .github || true
# Add download count to names
#build_list="$(head -n 1 Stats3)"
# shellcheck disable=SC2206
#build_list=($build_list)
# shellcheck disable=SC2013
#for var in "${build_list[@]:1}"; do
#i=0
#j=0
#k=0
# shellcheck disable=SC2013
# for i in $(sed -n "/${var}/p" Stats); do
# k="$((k+1))"
# if [ "$k" -eq 3 ]; then break; fi
# if [ "$i" -eq "$i" ] && [ "$i" -gt "$j" ]; then j="$i"; fi
# done
#sed -i "s|${var}|${var}_(${j}x)|g" Stats3
#done
echo "... done"
# Remove series with less than 4 points
sed -i "/^[0-9|-]* [0-9*|-]* [0-9*|-]* -/d" Stats3
# Plot graph
( gnuplot -persist <<-EOFMarker
set title 'Top 10 addons'
set ylabel 'Number of installations'
set xdata time
set datafile missing "-"
set timefmt "%Y-%m-%d"
set format x "%y-%m-%d"
set datafile sep ' '
set autoscale
set terminal png size 500,300
set output 'stats_addons.png'
set term png tiny
plot for [i=2:*] 'Stats3' using 1:i w l title columnhead(i) smooth bezier
EOFMarker
) || ( gnuplot -persist <<-EOFMarker
set title 'Top 10 addons'
set ylabel 'Number of installations'
set xdata time
set datafile missing "-"
set timefmt "%Y-%m-%d"
set format x "%y-%m-%d"
set datafile sep ' '
set autoscale
set terminal png size 500,300
set output 'stats_addons.png'
set term png tiny
plot for [i=2:*] 'Stats3' using 1:i w l title columnhead(i)
EOFMarker
)
#plot for [i=1:*] 'Stats3' using 0:i
rm Stats3
cd .. || true
- name: Create individual stats
run: |
# Prepare data
cp Stats Stats3
# Remove Totals
sed -i "2d" Stats3
# Inverse file
gawk -i inplace '{for(i=NF;i>1;i--)printf "%s ",$i;printf "%s",$1;print ""}' Stats3
# For each addon
# shellcheck disable=SC2013
for line in $(awk '{ print $1 }' Stats3); do
TITLE="${line%% *}"
FOLDER="$(grep -irl "ghcr.io/alexbelgium/$TITLE-{arch}" --include="config.*" . | xargs -r dirname)"
FOLDER="${FOLDER:2}"
echo "$TITLE found in $FOLDER"
# If non null
if [[ "${#FOLDER}" -gt 2 ]]; then
sed -n "/Date /p" Stats3 > "$FOLDER"/StatsTmp
sed -n "/$TITLE /p" Stats3 >> "$FOLDER"/StatsTmp
# Go in folder
cd "$FOLDER" || true
cat StatsTmp
# Transpose data
awk '
{
for (i=1; i<=NF; i++) {
a[NR,i] = $i
}
}
NF>p { p = NF }
END {
for(j=1; j<=p; j++) {
str=a[1,j]
for(i=2; i<=NR; i++){
str=str" "a[i,j];
}
print str
}
}' StatsTmp > StatsTmp2 && mv StatsTmp2 StatsTmp
#Normalize data
#awk 'FNR==NR{max=($2+0>max)?$2:max;next} {print $1,$2/max}' StatsTmp StatsTmp
# Plot graph
( gnuplot -persist <<-EOFMarker
set title "$TITLE"
set ylabel 'Number of installations'
set xdata time
set datafile missing "-"
set timefmt "%Y-%m-%d"
set format x "%y-%m-%d"
set datafile sep ' '
set autoscale
set terminal png size 500,150
set output "stats.png"
set term png tiny
plot for [i=2:*] 'StatsTmp' using 1:i w l title columnhead(i) smooth bezier
EOFMarker
) || ( gnuplot -persist <<-EOFMarker
set title "$TITLE"
set ylabel 'Number of installations'
set xdata time
set datafile missing "-"
set timefmt "%Y-%m-%d"
set format x "%y-%m-%d"
set datafile sep ' '
set autoscale
set terminal png size 500,150
set output "stats.png"
set term png tiny
plot for [i=2:*] 'StatsTmp' using 1:i w l title columnhead(i)
EOFMarker
) || true
rm StatsTmp || true
cd .. || true
fi || true
done
# Clean files
rm StatsTmp2
rm Stats3
- name: Create global stats
run: |
# Prepare data
cp Stats Stats3
# Inverse file
gawk -i inplace '{for(i=NF;i>1;i--)printf "%s ",$i;printf "%s",$1;print ""}' Stats3
# Only totals
head -n 2 Stats3 > tmp_file && mv tmp_file Stats3
# Transpose data
awk '
{
for (i=1; i<=NF; i++) {
a[NR,i] = $i
}
}
NF>p { p = NF }
END {
for(j=1; j<=p; j++) {
str=a[1,j]
for(i=2; i<=NR; i++){
str=str" "a[i,j];
}
print str
}
}' Stats3 > StatsTmp && mv StatsTmp .github/Stats3
cd .github || true
sed -i "1d" Stats3
# Plot graph
gnuplot -persist <<-EOFMarker
set title 'Total addons'
set ylabel 'Number of installations'
set xdata time
set datafile missing "-"
set timefmt "%Y-%m-%d"
set format x "%y-%m-%d"
set datafile sep ' '
set key top left autotitle columnheader
set autoscale
set terminal png size 500,300
set output 'stats.png'
set term png tiny
plot 'Stats3' using 1:2 lt rgb 'red' w l title 'Total addons' smooth bezier
EOFMarker
rm Stats3
cd .. || true
- name: Clean
run: |
echo "Starting run"
if [ -f stats.png ]; then rm stats.png; fi
if [ -f Stats3 ]; then rm Stats3; fi
- name: Update stars
run: |
echo "Starting run"
# Get stars
wget -S -O .github/stars.svg https://contrib.rocks/image?repo=Mesteriis/hassio-addons-avm || true
# Get stars2
wget -S -O .github/stars2.svg https://git-lister.onrender.com/api/stars/Mesteriis/hassio-addons-avm?limit=30 || true
# Get stars evolution
wget -S -O .github/starsevol.svg "https://api.star-history.com/svg?repos=Mesteriis/hassio-addons-avm&type=Date" || true
- name: Commit if needed
uses: EndBug/add-and-commit@v9
with:
message: "GitHub bot : graphs updated"
default_author: github_actions

View File

@@ -1,22 +0,0 @@
---
name: Sync labels
# yamllint disable-line rule:truthy
on:
push:
branches:
- master
paths:
- .github/labels.yml
jobs:
labels:
name: ♻️ Sync labels
runs-on: ubuntu-latest
steps:
- name: ⤵️ Check out code from GitHub
uses: actions/checkout@v2.3.4
- name: 🚀 Run Label Syncer
uses: micnncim/action-label-syncer@v1.3.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,33 +0,0 @@
---
name: Lint
# yamllint disable-line rule:truthy
on:
push:
pull_request:
types:
- opened
- reopened
- synchronize
workflow_dispatch:
jobs:
json:
name: JSON Lint
runs-on: ubuntu-latest
steps:
- name: ⤵️ Check out code from GitHub
uses: actions/checkout@v2.3.4
- name: 🚀 Run JQ
run: |
shopt -s globstar
cat **/*.json | jq '.'
yamllint:
name: YAMLLint
runs-on: ubuntu-latest
steps:
- name: ⤵️ Check out code from GitHub
uses: actions/checkout@v2.3.4
- name: 🚀 Run YAMLLint
uses: frenck/action-yamllint@v1.1

View File

@@ -1,21 +0,0 @@
---
name: Lock
# yamllint disable-line rule:truthy
on:
schedule:
- cron: "0 9 * * *"
workflow_dispatch:
jobs:
lock:
name: 🔒 Lock closed issues and PRs
runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@v2.0.3
with:
github-token: ${{ github.token }}
issue-lock-inactive-days: "30"
issue-lock-reason: ""
pr-lock-inactive-days: "1"
pr-lock-reason: ""

69
.github/workflows/on_issues.yml vendored Normal file
View File

@@ -0,0 +1,69 @@
# yamllint disable rule:line-length
---
name: Readme Issues linker
on:
issues:
types: [opened, edited, closed]
workflow_dispatch:
jobs:
ISSUES_linked:
runs-on: ubuntu-20.04
steps:
- name: Checkout Repo
uses: actions/checkout@v4
- name: Assign issues
run: |
# Init
echo "Starting"
# Get issues list
curl -s -L https://api.github.com/repos/Mesteriis/hassio-addons-avm/issues > issueslist
# Go through all folders, add to filters if not existing
for f in $( find -- * -maxdepth 0 -type d | sort -r ); do
if [ -f "$f"/config.json ]; then
# Clean previously reported issues
sed -i "/Open Issue :/d" "$f"/README.md
sed -i "/Open Request :/d" "$f"/README.md
# If there is an issue with the addon name in title, put a message
COUNTER=0
while [[ $(jq -r --arg COUNTER "$COUNTER" ".[$COUNTER].title" issueslist) != null ]]; do
#Increment counter
(( COUNTER=COUNTER+1 )) || true
#Get variables
TITLE="$(jq -r --arg COUNTER "$COUNTER" ".[$COUNTER].title" issueslist)"
TITLE="${TITLE//[<>\$\'\"]/}"
#Check if relevant to addon
SLUG="$(jq -r --arg f "$f" ".slug" "$f"/config.json)"
NAME="$(jq -r --arg f "$f" ".name" "$f"/config.json)"
if [[ "${TITLE,,}" == *"${f,,}"* ]] || [[ "${TITLE,,}" == *"${SLUG,,}"* ]] || [[ "${TITLE,,}" == *"${NAME,,}"* ]]; then
echo "Project $TITLE, $SLUG, $NAME has an issue"
REQ="$(jq -r --arg COUNTER "$COUNTER" ".[$COUNTER].user.login" issueslist)"
URL="$(jq -r --arg COUNTER "$COUNTER" ".[$COUNTER].html_url" issueslist)"
LABEL="$(jq -r --arg COUNTER "$COUNTER" ".[$COUNTER].labels[].name" issueslist)"
DATEISSUE="$(jq -r --arg COUNTER "$COUNTER" ".[$COUNTER].created_at" issueslist)"
DATEISSUE="${DATEISSUE%T*}"
if [[ "$LABEL" == *"bug"* ]]; then
sed -i "1i ## &#9888; Open Issue : [$TITLE (opened ${DATEISSUE})]($URL) by [@${REQ}](https://github.com/$REQ)" "$f"/README.md
elif [[ "$LABEL" == *"enhancement"* ]]; then
sed -i "1i ## &#9888; Open Request : [$TITLE (opened ${DATEISSUE})]($URL) by [@${REQ}](https://github.com/$REQ)" "$f"/README.md
fi
fi
done
fi
done
# Remove issues list
rm issueslist
- name: Commit if needed
uses: EndBug/add-and-commit@v9
with:
message: "Github bot : issues linked to readme"
default_author: github_actions
commit: -u
fetch: --force
push: --force

40
.github/workflows/onpr_automerge.yaml vendored Normal file
View File

@@ -0,0 +1,40 @@
# yamllint disable rule:line-length
# shellcheck disable=SC2043
---
name: automerge
on:
pull_request_review:
types:
- submitted
issue_comment:
types: created
check_suite:
types:
- completed
status: {}
jobs:
labeler:
runs-on: ubuntu-latest
steps:
- name: Add the automerge label
if: ${{ github.event.issue.pull_request && contains(github.event.comment.body, '/automerge') }}
uses: actions/github-script@v4
with:
github-token: ${{secrets.GITHUB_TOKEN}}
script: |
github.issues.addLabels({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
labels: ['automerge']
})
automerge:
runs-on: ubuntu-latest
needs: [labeler]
steps:
- id: automerge
if: ${{ github.event.issue.pull_request }}
name: automerge
uses: "pascalgn/automerge-action@v0.16.2"
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"

276
.github/workflows/onpr_check-pr.yaml vendored Normal file
View File

@@ -0,0 +1,276 @@
# yamllint disable rule:line-length
# shellcheck disable=SC2043
---
name: PR Check Build
on:
pull_request:
branches:
- master
jobs:
check-addon-changes:
runs-on: ubuntu-latest
outputs:
changedAddons: ${{ steps.filter.outputs.changes }}
changedChangelogFiles: ${{ steps.changed-files.outputs.changelogs_files }}
steps:
- name: ↩️ Checkout
uses: actions/checkout@v4
- name: 📂 Detect changed addons
uses: dorny/paths-filter@v3
id: filter
with:
filters: .github/paths-filter.yml
- name: 📂 Detect chanced files
uses: dorny/paths-filter@v3
id: changed-files
with:
list-files: csv
filters: |
changelogs:
- '**/CHANGELOG.md'
check-changed-changelog:
name: Check if CHANGELOG.md changed
if: ${{ needs.check-addon-changes.outputs.changedAddons != '[]' }}
runs-on: ubuntu-latest
needs: check-addon-changes
strategy:
fail-fast: false
matrix:
addon: ${{ fromJSON(needs.check-addon-changes.outputs.changedAddons) }}
steps:
- name: 🔎 Check for updated CHANGELOG.md
shell: bash
run: |
# shellcheck disable=SC2076,SC2059
if [[ ! "${{ needs.check-addon-changes.outputs.changedChangelogFiles }}" =~ "${{ matrix.addon }}/CHANGELOG.md" ]]; then
echo "::error::No new entries in ${{ matrix.addon }} CHANGELOG.md file!"
exit 1
fi
check-addon-label:
name: Check for existance of the addon label
if: ${{ needs.check-addon-changes.outputs.changedAddons != '[]' }}
runs-on: ubuntu-latest
needs: check-addon-changes
strategy:
fail-fast: false
matrix:
addon: ${{ fromJSON(needs.check-addon-changes.outputs.changedAddons) }}
steps:
- name: ↩️ Checkout
uses: actions/checkout@v4
- name: 🔎 Check if a label for the addon exists
shell: bash
run: |
labeltext=$(sed -nr "/${{ matrix.addon }}/p" '.github/paths-filter.yml')
if [[ -z "$labeltext" ]]; then
echo "::error::There is no label for this addon! Please add it to .github/paths-filter.yml"
exit 1
fi
addon-linter:
name: Addon linting
if: ${{ needs.check-addon-changes.outputs.changedAddons != '[]' }}
runs-on: ubuntu-latest
needs: check-addon-changes
strategy:
fail-fast: false
matrix:
addon: ${{ fromJSON(needs.check-addon-changes.outputs.changedAddons) }}
steps:
- name: ↩️ Checkout
uses: actions/checkout@v4
- name: 🔎 Run Home Assistant Add-on Lint
uses: frenck/action-addon-linter@v2
with:
path: "./${{ matrix.addon }}"
check-build:
name: Test addon build
if: ${{ needs.check-addon-changes.outputs.changedAddons != '[]' }}
runs-on: ubuntu-latest
needs: check-addon-changes
strategy:
fail-fast: false
matrix:
addon: ${{ fromJSON(needs.check-addon-changes.outputs.changedAddons) }}
steps:
- name: ↩️ Checkout
uses: actions/checkout@v4
- name: Gather addon info
id: information
uses: frenck/action-addon-information@v1.4
with:
path: "./${{ matrix.addon }}/"
- name: 🗄️ Cache docker layers
uses: actions/cache@v3
with:
path: /tmp/buildx-cache
key: ${{ runner.os }}-buildx-${{ matrix.addon }}-${{ hashFiles('**/Dockerfile') }}
restore-keys: ${{ runner.os }}-buildx-${{ matrix.addon }}-
- name: 🔖 Create addon image tags
id: tags
shell: bash
run: |
imagetemplate=${{ steps.information.outputs.image }}
version=${{ steps.information.outputs.version }}
echo "Using imagetemplate '$imagetemplate'"
# shellcheck disable=SC2129
echo "armhf=${imagetemplate/\{arch\}/armhf}:${version}" >> "$GITHUB_OUTPUT"
# shellcheck disable=SC2129
echo "armv7=${imagetemplate/\{arch\}/armv7}:${version}" >> "$GITHUB_OUTPUT"
# shellcheck disable=SC2129
echo "aarch64=${imagetemplate/\{arch\}/aarch64}:${version}" >> "$GITHUB_OUTPUT"
# shellcheck disable=SC2129
echo "amd64=${imagetemplate/\{arch\}/amd64}:${version}" >> "$GITHUB_OUTPUT"
# shellcheck disable=SC2129
echo "i386=${imagetemplate/\{arch\}/i386}:${version}" >> "$GITHUB_OUTPUT"
- name: 🏷️ Create addon labels
id: labels
shell: bash
run: |
exit 0
# shellcheck disable=SC2076,SC2059
labels="io.hass.version=${{ steps.information.outputs.version }}"
labels=$(printf '%s' "$labels\nio.hass.name=${{ steps.information.outputs.name }}")
labels=$(printf '%s' "$labels\nio.hass.description=${{ steps.information.outputs.description }}")
labels=$(printf '%s' "$labels\nio.hass.type=addon")
labels=$(printf '%s' "$labels\nio.hass.url=${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/tree/master/${{ matrix.addon }}")
labels=$(printf '%s' "$labels\norg.opencontainers.image.title=${{ steps.information.outputs.name }}")
labels=$(printf '%s' "$labels\norg.opencontainers.image.description=${{ steps.information.outputs.description }}")
labels=$(printf '%s' "$labels\norg.opencontainers.image.version=${{ steps.information.outputs.version }}")
labels=$(printf '%s' "$labels\norg.opencontainers.image.authors=Poeschl <Poeschl@users.noreply.github.com>")
labels=$(printf '%s' "$labels\norg.opencontainers.image.url=${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}")
labels=$(printf '%s' "$labels\norg.opencontainers.image.source=${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/tree/master/${{ matrix.addon }}")
labels=$(printf '%s' "$labels\norg.opencontainers.image.created=$(date -Is)")
labels=$(printf '%s' "$labels\norg.opencontainers.image.revision=${GITHUB_SHA}")
echo "Generic labels: $labels"
armhf_labels=$(printf '%s' "$labels\nio.hass.arch=armhf")
armv7_labels=$(printf '%s' "$labels\nio.hass.arch=armv7")
aarch64_labels=$(printf '%s' "$labels\nio.hass.arch=aarch64")
amd64_labels=$(printf '%s' "$labels\nio.hass.arch=amd64")
i386_labels=$(printf '%s' "$labels\nio.hass.arch=i386")
# allow multiline outputs, see https://github.community/t/set-output-truncates-multiline-strings/16852
armhf_labels="${armhf_labels//$'\n'/'%0A'}"
armv7_labels="${armv7_labels//$'\n'/'%0A'}"
aarch64_labels="${aarch64_labels//$'\n'/'%0A'}"
amd64_labels="${amd64_labels//$'\n'/'%0A'}"
i386_labels="${i386_labels//$'\n'/'%0A'}"
# shellcheck disable=SC2129
echo "armhf=$armhf_labels" >> "$GITHUB_OUTPUT"
# shellcheck disable=SC2129
echo "armv7=$armv7_labels" >> "$GITHUB_OUTPUT"
# shellcheck disable=SC2129
echo "aarch64=$aarch64_labels" >> "$GITHUB_OUTPUT"
# shellcheck disable=SC2129
echo "amd64=$amd64_labels" >> "$GITHUB_OUTPUT"
# shellcheck disable=SC2129
echo "i386=$i386_labels" >> "$GITHUB_OUTPUT"
- name: 💽 Create addon build-args
id: build_args
shell: bash
run: |
# shellcheck disable=SC2129
echo "armhf=BUILD_FROM=$(jq -r .build_from.armhf // empty ${{ steps.information.outputs.build }})" >> "$GITHUB_OUTPUT"
# shellcheck disable=SC2129
echo "armv7=BUILD_FROM=$(jq -r .build_from.armv7 // empty ${{ steps.information.outputs.build }})" >> "$GITHUB_OUTPUT"
# shellcheck disable=SC2129
echo "aarch64=BUILD_FROM=$(jq -r .build_from.aarch64 // empty ${{ steps.information.outputs.build }})" >> "$GITHUB_OUTPUT"
# shellcheck disable=SC2129
echo "amd64=BUILD_FROM=$(jq -r .build_from.amd64 // empty ${{ steps.information.outputs.build }})" >> "$GITHUB_OUTPUT"
# shellcheck disable=SC2129
echo "i386=BUILD_FROM=$(jq -r .build_from.i386 // empty ${{ steps.information.outputs.build }})" >> "$GITHUB_OUTPUT"
- name: 🏗️ Set up QEMU
uses: docker/setup-qemu-action@v3
- name: 🏗️ Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: 💿 Build Addon - armhf
if: ${{ steps.information.outputs.armhf == 'true' }}
uses: docker/build-push-action@v5
with:
context: ${{ matrix.addon }}
push: false
load: true
file: ${{ matrix.addon }}/Dockerfile
tags: ${{ steps.tags.outputs.armhf }}
labels: |
${{ steps.labels.outputs.armhf }}
build-args: ${{ steps.build_args.outputs.armhf }}
cache-from: type=local,src=/tmp/buildx-cache/armhf
cache-to: type=local,dest=/tmp/buildx-cache-new/armhf
- name: 💿 Build Addon - armv7
if: ${{ steps.information.outputs.armv7 == 'true' }}
uses: docker/build-push-action@v5
with:
context: ${{ matrix.addon }}
push: false
load: true
file: ${{ matrix.addon }}/Dockerfile
tags: ${{ steps.tags.outputs.armv7 }}
labels: |
${{ steps.labels.outputs.armv7 }}
build-args: ${{ steps.build_args.outputs.armv7 }}
cache-from: type=local,src=/tmp/buildx-cache/armv7
cache-to: type=local,dest=/tmp/buildx-cache-new/armv7
- name: 💿 Build Addon - aarch64
if: ${{ steps.information.outputs.aarch64 == 'true' }}
uses: docker/build-push-action@v5
with:
context: ${{ matrix.addon }}
push: false
load: true
file: ${{ matrix.addon }}/Dockerfile
tags: ${{ steps.tags.outputs.aarch64 }}
labels: |
${{ steps.labels.outputs.aarch64 }}
build-args: ${{ steps.build_args.outputs.aarch64 }}
cache-from: type=local,src=/tmp/buildx-cache/aarch64
cache-to: type=local,dest=/tmp/buildx-cache-new/aarch64
- name: 💿 Build Addon - amd64
if: ${{ steps.information.outputs.amd64 == 'true' }}
uses: docker/build-push-action@v5
with:
context: ${{ matrix.addon }}
push: false
load: true
file: ${{ matrix.addon }}/Dockerfile
tags: ${{ steps.tags.outputs.amd64 }}
labels: |
${{ steps.labels.outputs.amd64 }}
build-args: ${{ steps.build_args.outputs.amd64 }}
cache-from: type=local,src=/tmp/buildx-cache/amd64
cache-to: type=local,dest=/tmp/buildx-cache-new/amd64
- name: 💿 Build Addon - i386
if: ${{ steps.information.outputs.i386 == 'true' }}
uses: docker/build-push-action@v5
with:
context: ${{ matrix.addon }}
push: false
load: true
file: ${{ matrix.addon }}/Dockerfile
tags: ${{ steps.tags.outputs.i386 }}
labels: |
${{ steps.labels.outputs.i386 }}
build-args: ${{ steps.build_args.outputs.i386 }}
cache-from: type=local,src=/tmp/buildx-cache/i386
cache-to: type=local,dest=/tmp/buildx-cache-new/i386
# Fix for https://github.com/docker/build-push-action/issues/252
- name: 🗄️ Update cache Folder
run: |
rm -rf /tmp/buildx-cache
mv /tmp/buildx-cache-new /tmp/buildx-cache

232
.github/workflows/onpush_builder.yaml vendored Normal file
View File

@@ -0,0 +1,232 @@
# yamllint disable rule:line-length
# inspired from https://github.com/Poeschl/Hassio-Addons
---
name: Builder
env:
BUILD_ARGS: ""
on:
workflow_call:
push:
branches:
- master
paths:
- "**/config.*"
jobs:
correct_path_filters:
runs-on: ubuntu-latest
steps:
- name: ↩️ Checkout
uses: actions/checkout@v4
- name: Update path_filters
run: |
# Init
echo "Starting"
# Go through all folders, add to filters if not existing
for f in $( find -- * -maxdepth 0 -type d | sort -r ); do
if [ -f "$f"/config.json ]; then
# Add to file
if ! grep "$f:" ".github/paths-filter.yml"; then
echo "$f: $f/config.*" >> ".github/paths-filter.yml"
fi
# Identify addons with true images
if [ "$(jq '.image' "$f/config.json")" != null ]; then
sed -i "/$f/ s/ # Image : yes//g" ".github/paths-filter.yml"
sed -i "/$f/ s/$/ # Image : yes/" ".github/paths-filter.yml"
fi
fi
done
# Sort yaml
sort -t= ".github/paths-filter.yml" -o ".github/paths-filter.yml"
- name: Commit if needed
uses: EndBug/add-and-commit@v9
with:
commit: -u
message: "GitHub bot : scripts executable"
default_author: github_actions
check-addon-changes:
runs-on: ubuntu-latest
needs: [correct_path_filters]
outputs:
changedAddons: ${{ steps.filter.outputs.changes }}
steps:
- name: ↩️ Checkout
uses: actions/checkout@v4
- name: 📂 Detect changed files
uses: dorny/paths-filter@v3
id: filter
with:
filters: .github/paths-filter.yml
correct-CRLF:
if: ${{ needs.check-addon-changes.outputs.changedAddons != '[]' }}
needs: check-addon-changes
uses: ./.github/workflows/weekly_crlftolf.yaml
make-executable:
if: ${{ needs.check-addon-changes.outputs.changedAddons != '[]' }}
needs: [check-addon-changes, correct-CRLF]
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
addon: ${{ fromJSON(needs.check-addon-changes.outputs.changedAddons) }}
steps:
- name: Checkout Repo
uses: actions/checkout@v4
- name: Make scripts executable
run: |
echo "Starting"
git pull origin master
git config core.filemode true
# shellcheck disable=SC2086,SC2046
#git update-index --chmod=+x $(find "$path" -type f -iname "*.sh")
chmod u+x $(find "$path" -type f -iname "*.sh") || true
#git commit -am "fixing the script permissions..."
env:
path: "./${{ matrix.addon }}"
- name: Commit if needed
uses: EndBug/add-and-commit@v9
with:
commit: -u
message: "GitHub bot : scripts executable"
default_author: github_actions
lint_config:
if: ${{ needs.check-addon-changes.outputs.changedAddons != '[]' }}
needs: check-addon-changes
runs-on: ubuntu-latest
strategy:
matrix:
addon: ${{ fromJSON(needs.check-addon-changes.outputs.changedAddons) }}
steps:
- name: ↩️ Checkout
uses: actions/checkout@v4
- name: 🔎 Run Home Assistant Add-on Lint
uses: frenck/action-addon-linter@v2
with:
path: "./${{ matrix.addon }}"
build:
if: ${{ needs.check-addon-changes.outputs.changedAddons != '[]' }}
needs: [check-addon-changes, make-executable, correct-CRLF]
runs-on: ubuntu-latest
environment: CR_PAT
name: Build ${{ matrix.arch }} ${{ matrix.addon }} add-on
strategy:
matrix:
addon: ${{ fromJSON(needs.check-addon-changes.outputs.changedAddons) }}
arch: ["aarch64", "amd64", "armv7"]
steps:
- name: Check out repository
uses: actions/checkout@v4
- name: Get information
id: info
uses: home-assistant/actions/helpers/info@master
with:
path: "./${{ matrix.addon }}"
- name: Check if add-on should be built
id: check
env:
HEAD: "${{ github.head_ref }}"
run: |
# shellcheck disable=SC2157,SC2086
if [[ "${{ steps.info.outputs.architectures }}" =~ ${{ matrix.arch }} ]]; then
# shellcheck disable=SC2129
echo "build_arch=true" >> $GITHUB_OUTPUT;
# shellcheck disable=SC2129
echo "image=$(echo ${{ steps.info.outputs.image }} | cut -d'/' -f3)" >> $GITHUB_OUTPUT;
if [[ -z "$HEAD" ]] && [[ "${{ github.event_name }}" == "push" ]]; then
# shellcheck disable=SC2129
echo "BUILD_ARGS=" >> $GITHUB_ENV;
fi
else
echo "${{ matrix.arch }} is not a valid arch for ${{ matrix.addon }}, skipping build";
# shellcheck disable=SC2129
echo "build_arch=false" >> $GITHUB_OUTPUT;
fi
- name: Use action to check for mixed line endings (CRLF and LF)
uses: ymwymw/check-mixed-line-endings@v2
- name: Login to GitHub Container Registry
if: env.BUILD_ARGS != '--test'
uses: docker/login-action@v3.1.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build ${{ matrix.addon }} add-on
id: builderstep
if: steps.check.outputs.build_arch == 'true'
uses: home-assistant/builder@master
env:
CAS_API_KEY: ${{ secrets.CAS_API_KEY }}
with:
args: |
${{ env.BUILD_ARGS }} \
--${{ matrix.arch }} \
--target /data/${{ matrix.addon }} \
--image "${{ steps.check.outputs.image }}" \
--docker-hub "ghcr.io/${{ github.repository_owner }}" \
--addon
make-changelog:
if: ${{ needs.check-addon-changes.outputs.changedAddons != '[]' }}
needs: [check-addon-changes, build]
runs-on: ubuntu-latest
strategy:
matrix:
addon: ${{ fromJSON(needs.check-addon-changes.outputs.changedAddons) }}
steps:
- name: Checkout Repo
uses: actions/checkout@v4
- name: Update changelog for minor versions
run: |
echo "Starting"
# Git pull
git pull || true
cd "$path"
# Get version
if [ -f config.yaml ]; then
version="$(sed -e '/version/!d' -e 's/.*version: //' config.yaml)"
elif [ -f config.json ]; then
version="$(sed -e '/version/!d' -e 's/.*[^"]*"\([^"]*\)"/\1/' config.json)"
version="${version//,}"
else
exit 1
fi
# Exit if test
if [[ "$version" == *"test"* ]]; then exit 0; fi
# Create changelog
touch CHANGELOG.md
# If the version does not exist
if ! grep -q "$version" CHANGELOG.md; then
first_line="$(sed -n '/./p' CHANGELOG.md | head -n 1)"
# If the first line does not start with -
if [[ "$first_line" != "-"* ]]; then
sed -i "1i\- Minor bugs fixed" CHANGELOG.md
fi
sed -i "1i\## $version ($(date '+%d-%m-%Y'))" CHANGELOG.md
#fi
fi
env:
path: "./${{ matrix.addon }}"
- name: Commit if needed
uses: EndBug/add-and-commit@v9
with:
commit: -u
message: "GitHub bot : changelog"
default_author: github_actions
fetch: --force
push: --force

View File

@@ -0,0 +1,32 @@
# This workflow executes several linters on changed files based on languages used in your code base whenever
# you push a code or open a pull request.
#
# You can adjust the behavior by modifying this file.
# For more information, see:
# https://github.com/github/super-linter
---
name: Lint On Change
on:
push:
branches: [ master ]
pull_request:
branches: [ master ]
jobs:
run-lint:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
# Full git history is needed to get a proper list of changed files within `super-linter`
fetch-depth: 0
- name: Lint Code Base
uses: docker://github/super-linter:slim-v4
env:
VALIDATE_ALL_CODEBASE: false
DEFAULT_BRANCH: master
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VALIDATE_NATURAL_LANGUAGE: false

View File

@@ -1,54 +0,0 @@
---
name: Repository Updater
# yamllint disable-line rule:truthy
on:
repository_dispatch:
types: ["update"]
jobs:
publish:
name: Publish add-on update
runs-on: ubuntu-latest
steps:
- name: 🚀 Run Repository Updater
uses: hassio-addons/repository-updater@v1.1
with:
addon: ${{ github.event.client_payload.addon }}
repository: ${{ github.repository }}
token: ${{ secrets.UPDATER_TOKEN }}
announce:
name: Announce add-on update
needs: publish
runs-on: ubuntu-latest
steps:
- name: 📢 Announce on Discord server
uses: sarisia/actions-status-discord@v1.8.6
with:
webhook: ${{ secrets.DISCORD_WEBHOOK }}
nodetail: true
username: ${{ github.event.client_payload.name }}
avatar_url: |
https://raw.githubusercontent.com/${{ github.repository }}/master/${{ github.event.client_payload.addon }}/icon.png
title: ":arrow_up: ${{ github.event.client_payload.name }} ${{ github.event.client_payload.version }}"
image: |
https://raw.githubusercontent.com/${{ github.repository }}/master/${{ github.event.client_payload.addon }}/logo.png
description: |
A new version of the ${{ github.event.client_payload.name }} add-on has been published.
**Version**: `${{ github.event.client_payload.version }}`
**Release notes**:
<https://github.com/${{ github.event.client_payload.repository }}/releases/tag/${{ github.event.client_payload.version }}>
- name: 📢 Announce on Twitter
uses: devigned/go-twitter-action@v1.0.2
with:
apiKey: ${{ secrets.TWITTER_API_KEY }}
apiKeySecret: ${{ secrets.TWITTER_API_SECRET }}
accessToken: ${{ secrets.TWITTER_ACCESS_TOKEN }}
accessTokenSecret: ${{ secrets.TWITTER_ACCESS_SECRET }}
message: |
⬆️ ${{ github.event.client_payload.name }} ${{ github.event.client_payload.version }}
https://github.com/${{ github.event.client_payload.repository }}/releases/tag/${{ github.event.client_payload.version }}

View File

@@ -1,40 +0,0 @@
---
name: Stale
# yamllint disable-line rule:truthy
on:
schedule:
- cron: "0 8 * * *"
workflow_dispatch:
jobs:
stale:
name: 🧹 Clean up stale issues and PRs
runs-on: ubuntu-latest
steps:
- name: 🚀 Run stale
uses: actions/stale@v3.0.19
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
days-before-stale: 30
days-before-close: 7
remove-stale-when-updated: true
stale-issue-label: "stale"
exempt-issue-labels: "no-stale,help-wanted"
stale-issue-message: >
There hasn't been any activity on this issue recently, so we
clean up some of the older and inactive issues.
Please make sure to update to the latest version and
check if that solves the issue. Let us know if that works for you
by leaving a comment 👍
This issue has now been marked as stale and will be closed if no
further activity occurs. Thanks!
stale-pr-label: "stale"
exempt-pr-labels: "no-stale"
stale-pr-message: >
There hasn't been any activity on this pull request recently. This
pull request has been automatically marked as stale because of that
and will be closed if no further activity occurs within 7 days.
Thank you for your contributions.

View File

@@ -1,75 +0,0 @@
---
name: Translations Download
# yamllint disable-line rule:truthy
on:
schedule:
- cron: "0 8 * * *"
workflow_dispatch:
workflow_run:
workflows: ["Translations Upload"]
branches: [master]
types:
- completed
jobs:
json:
name: Download Translations
runs-on: ubuntu-latest
steps:
- name: ⤵️ Check out code from GitHub
uses: actions/checkout@v2.3.4
with:
fetch-depth: 0
- name: 🏗 Set up yq
uses: frenck/action-setup-yq@v1.0.0
- name: 🏗 Set up the Lokalise CLI
uses: frenck/action-setup-lokalise@v1.0.0
- name: ⤵️ Download translations
run: |
echo "Downloading translations to lokalise"
lokalise2 file download \
--token "${LOKALISE_TOKEN}" \
--project-id "${LOKALISE_PROJECT}" \
--format yaml \
--original-filenames=false \
--export-empty-as base \
--bundle-structure ".translations/%LANG_ISO%.yaml"
env:
LOKALISE_TOKEN: ${{ secrets.LOKALISE_TOKEN }}
LOKALISE_PROJECT: ${{ secrets.LOKALISE_PROJECT }}
- name: 🚀 Process translations
run: |
addons=$(yq e '.addons | keys | .[]' .addons.yml)
mkdir -p .translations
for file in .translations/*.yaml;
do
filename=$(basename "${file}")
language="${filename%.*}"
if [[ "${language}" == "en" ]]; then
continue
fi
echo "Processing downloaded translations in ${language}..."
while read addon;
do
if [[ -f "${addon}/translations/en.yaml" ]];
then
echo "Processing downloaded translations in ${language} for ${addon}..."
yq e ".${addon}" "${file}" \
> "${addon}/translations/${filename}"
fi
done <<<"${addons}"
done
- name: 🚀 Commit changes
continue-on-error: true
run: |
git config --local user.email "action@github.com"
git config --local user.name "${GITHUB_ACTOR}"
git add .
git commit -m "🌍 Updating translations" -a
- name: 🚀 Push changes
uses: ad-m/github-push-action@v0.6.0
continue-on-error: true
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
branch: ${{ github.ref }}

View File

@@ -1,53 +0,0 @@
---
name: Translations Upload
# yamllint disable-line rule:truthy
on:
workflow_dispatch:
workflow_run:
workflows: ["Repository Updater"]
branches: [master]
types:
- completed
jobs:
upload:
name: Upload Translations
runs-on: ubuntu-latest
steps:
- name: ⤵️ Check out code from GitHub
uses: actions/checkout@v2.3.4
- name: 🏗 Set up yq
uses: frenck/action-setup-yq@v1.0.0
- name: 🏗 Set up the Lokalise CLI
uses: frenck/action-setup-lokalise@v1.0.0
- name: 🚀 Combine translations
run: |
addons=$(yq e '.addons | keys | .[]' .addons.yml)
mkdir -p .translations
while read addon;
do
if [[ -f "${addon}/translations/en.yaml" ]];
then
echo "Prepping translation upload for $addon..."
ADDON="${addon}" \
yq e '{env(ADDON): .}' "${addon}/translations/en.yaml" \
> ".translations/${addon}.yaml"
fi
done <<<"${addons}"
echo "Combining translation files..."
yq ea '. as $item ireduce ({}; . * $item)' ./.translations/*.yaml > translations.yaml
- name: 🚀 Upload translations
run: |
echo "Uploading translations to lokalise"
lokalise2 file upload \
--apply-tm \
--lang-iso en \
--poll \
--token "${LOKALISE_TOKEN}" \
--project-id "${LOKALISE_PROJECT}" \
--file translations.yaml
env:
LOKALISE_TOKEN: ${{ secrets.LOKALISE_TOKEN }}
LOKALISE_PROJECT: ${{ secrets.LOKALISE_PROJECT }}

View File

@@ -0,0 +1,76 @@
# This workflow executes several linters on changed files based on languages used in your code base whenever
# you push a code or open a pull request.
#
# You can adjust the behavior by modifying this file.
# For more information, see:
# https://github.com/github/super-linter
---
name: Lint Code Base
on:
schedule:
- cron: "0 0 * * 0"
workflow_dispatch:
jobs:
make-executable:
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@v4
- name: Make scripts executable
run: |
echo "Starting"
git config core.filemode true
# shellcheck disable=SC2086,SC2046
#git update-index --chmod=+x $(find . -type f -iname "*.sh")
chmod u+x $(find . -type f -iname "*.sh")
#git commit -am "fixing the script permissions..."
- name: Commit if needed
uses: EndBug/add-and-commit@v9
with:
commit: -u
message: "GitHub bot : scripts executable"
default_author: github_actions
run-lint:
runs-on: ubuntu-latest
needs: make-executable
steps:
##########################
# Checkout the code base #
##########################
- name: Checkout the code base
uses: actions/checkout@v4
with:
# Full git history is needed to get a proper list of changed files within `super-linter`
fetch-depth: 0
####################
# Run Super Linter #
####################
- name: Lint Code Base
uses: docker://github/super-linter:slim-v4
env:
VALIDATE_ALL_CODEBASE: true
DEFAULT_BRANCH: master
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
VALIDATE_NATURAL_LANGUAGE: false
ACTION_ACTIONLINT_DISABLE_ERRORS: true
check_crlf:
name: Check CRLF action
runs-on: ubuntu-latest
steps:
- name: Checkout repository contents
uses: actions/checkout@v4
- name: Use action to check for CRLF endings
uses: erclu/check-crlf@v1.2.0
- name: check-mixed-line-endings
uses: ymwymw/check-mixed-line-endings@v2

36
.github/workflows/weekly_addons_updater vendored Normal file
View File

@@ -0,0 +1,36 @@
# yamllint disable rule:line-length
---
name: Weekly addons update
on:
workflow_call:
workflow_dispatch:
jobs:
stats_graphs:
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@v3
- name: Install bashio
run: |
# Install bashio
if grep -q -rnw "$files/" -e 'bashio' && [ ! -f "/usr/bin/bashio" ]; then
[ "$VERBOSE" = true ] && echo "install bashio"
BASHIO_VERSION="0.14.3"
mkdir -p /tmp/bashio
curl -f -L -s -S "https://github.com/hassio-addons/bashio/archive/v${BASHIO_VERSION}.tar.gz" | tar -xzf - --strip 1 -C /tmp/bashio
mv /tmp/bashio/lib /usr/lib/bashio
ln -s /usr/lib/bashio/bashio /usr/bin/bashio
rm -rf /tmp/bashio
fi
- name: Run script
run: |
mkdir -p /data
echo "{" >> /data/config.json
echo " repository=\"Mesteriis/hassio-addons-avm\"," >> /data/config.json
echo " gituser=\"Mesteriis/hassio-addons-avm\"," >> /data/config.json
echo " gitapi=\"Mesteriis/hassio-addons-avm\"," >> /data/config.json
echo " gitmail=\"Mesteriis/hassio-addons-avm\"," >> /data/config.json
echo " verbose=false" >> /data/config.json
echo "}" >> /data/config.json
./addons_updater/rootfs/etc/cont-init.d/99-run.sh

View File

@@ -0,0 +1,43 @@
name: Weekly bash beautify
on:
schedule:
- cron: "0 0 * * 0"
workflow_dispatch:
concurrency:
group: lint-bash-${{ github.head_ref || github.ref }}
cancel-in-progress: true
jobs:
lint-bash:
name: Lint Bash Scripts
runs-on: ubuntu-latest
steps:
- name: Checkout Git Repository
uses: actions/checkout@v4
- name: Set up Python Environment
uses: actions/setup-python@v4
with:
python-version: "3.11"
- name: Install Beautysh
run: pip install beautysh
- name: Run Beautysh
run: |
find . -name '*.sh' -print0 | xargs -0 beautysh --indent-size 4
shopt -s globstar nullglob
if compgen -G "**/*.sh" > /dev/null; then
beautysh -- **/*.sh --indent-size 4 --check
fi
shopt -u globstar nullglob
- name: Create New Pull Request If Needed
uses: peter-evans/create-pull-request@v5
with:
title: "Github bot : script beautyshied"
branch-suffix: timestamp
commit-message: "Github bot : script beautyshied"

54
.github/workflows/weekly_crlftolf.yaml vendored Normal file
View File

@@ -0,0 +1,54 @@
# yamllint disable rule:line-length
---
# This workflow finds and fixes CRLF endings in a repository
name: Fix CRLF Endings
on:
workflow_call:
workflow_dispatch:
jobs:
crlf-to-lf:
runs-on: ubuntu-latest
steps:
- name: Checkout repository contents
uses: actions/checkout@v4
- name: Use action to check for CRLF endings
uses: erclu/check-crlf@v1
- name: Commit if needed
uses: EndBug/add-and-commit@v9
with:
message: "Github bot : CRLF corrected"
default_author: github_actions
fix-crlf:
name: Fix CRLF Endings
runs-on: ubuntu-latest # Use a Linux runner
steps:
- name: Checkout repository contents
uses: actions/checkout@v4 # Use the checkout action
- name: Find files with CRLF endings
uses: erclu/check-crlf@v1.2.0 # Use the check-crlf action
id: check-crlf # Assign an id to this step
with:
# Specify the paths to check
path: |
./*
!.git
!*.png
!*.jpg
!*.bin
- name: Apply dos2unix to files with CRLF endings
run: |
# Loop through each file and apply dos2unix
# shellcheck disable=SC2043
for f in ${{ steps.check-crlf.outputs.files }}; do
# Apply dos2unix and keep the original timestamp
dos2unix -k "$f"
done
- name: Commit if needed
uses: EndBug/add-and-commit@v9
with:
message: "Github bot : CRLF corrected"
default_author: github_actions

View File

@@ -0,0 +1,37 @@
# Compress images on demand (workflow_dispatch), and at 11pm every Sunday (schedule).
# Open a Pull Request if any images can be compressed.
---
name: Compress Images
on:
workflow_dispatch:
schedule:
- cron: '00 23 * * 0'
jobs:
calibre:
name: calibreapp/image-actions
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
uses: actions/checkout@v4
- name: Compress Images
id: calibre
uses: calibreapp/image-actions@main
with:
# The `GITHUB_TOKEN` is automatically generated by GitHub and scoped only to the repository that is currently running the action. By default, the action cant update Pull Requests initiated from forked repositories.
# See https://docs.github.com/en/actions/reference/authentication-in-a-workflow and https://help.github.com/en/articles/virtual-environments-for-github-actions#token-permissions
githubToken: ${{ secrets.GITHUB_TOKEN }}
compressOnly: true
jpegQuality: '60'
jpegProgressive: false
pngQuality: '60'
webpQuality: '60'
- name: Commit if needed
if: steps.calibre.outputs.markdown != ''
uses: EndBug/add-and-commit@v9
with:
message: "Github bot : image compressed"
default_author: github_actions
body: ${{ steps.calibre.outputs.markdown }}

31
.github/workflows/weekly_sortjson.yaml vendored Normal file
View File

@@ -0,0 +1,31 @@
# yamllint disable rule:line-length
---
name: Weekly sort json
on:
schedule:
- cron: "0 0 * * 0"
workflow_dispatch:
jobs:
sort_json:
runs-on: ubuntu-20.04
steps:
- name: Checkout Repo
uses: actions/checkout@v4
- name: Run script file
id: sort
run: |
for files in */*.json; do
echo "Sorting $files"
jq --sort-keys . "$files" > config2.json && cat config2.json > "$files" && rm config2.json
echo "changed=1" >> "$GITHUB_OUTPUT"
done
shell: bash
- name: Create New Pull Request If Needed
if: steps.sort.outputs.changed != ''
uses: peter-evans/create-pull-request@v5
with:
title: "Github bot : json sorted"
branch-suffix: timestamp
commit-message: "Github bot : json sorted"

106
.github/workflows/weekly_stats.yaml vendored Normal file
View File

@@ -0,0 +1,106 @@
# yamllint disable rule:line-length
---
name: Generate weekly stats
on:
schedule:
- cron: "0 12 * * 5"
workflow_dispatch:
jobs:
stats_updater:
runs-on: ubuntu-20.04
steps:
- name: Checkout Repo
uses: actions/checkout@v4
- name: Create stats
run: |
echo "Starting"
COUNT=0
COUNT1=0
COUNT2=0
COUNT3=0
# Make sure file exists
file=Stats
touch "$file"
rm "$file"2
if ! grep -q "Date" "$file"; then
sed -i "1i Date" "$file"
fi
# Add new column
sed -i 's/^/- /' "$file"
# Add date
sed -i "/Date/s|^-|$(date '+%Y-%m-%d')|" "$file"
# Go through all folders, add to filters if not existing
# shellcheck disable=SC2086
for f in $( find -- * -maxdepth 0 -type d | sort -r ); do
DOWNLOADS=0
if [ -f "$f"/config.json ] && jq -e '.image' "$f/config.json"; then
SLUG="$(jq -r '.image' "$f/config.json" | awk -F 'alexbelgium/|-{arch' '{print $2}')"
if [[ "$(jq '.arch[]' "$f/config.json")" == *"armv7"* ]]; then
ARCH=armv7 && COUNT="$(curl --connect-timeout 5 -f -s -L https://github.com/Mesteriis/hassio-addons-avm/pkgs/container/$SLUG-$ARCH/latest | awk '/Total downloads/{getline; print}' | awk -F '<|>' '{print $3}')"
until [ -n "$COUNT" ]; do COUNT="$(curl --connect-timeout 5 -f -s -L https://github.com/Mesteriis/hassio-addons-avm/pkgs/container/$SLUG-$ARCH/latest | awk '/Total downloads/{getline; print}' | awk -F '<|>' '{print $3}')" && sleep 5; ((c++)) && echo "repeat $c" && if [[ "$c" == 10 ]]; then count=0; fi; done
COUNT="${COUNT//,/}"
COUNT1="$COUNT"
echo "$COUNT $ARCH users with $SLUG" && DOWNLOADS="$(( DOWNLOADS + COUNT))"
else COUNT1="-"; fi
if [[ "$(jq '.arch[]' "$f/config.json")" == *"amd64"* ]]; then
ARCH=amd64 && COUNT="$(curl --connect-timeout 5 -f -s -L https://github.com/Mesteriis/hassio-addons-avm/pkgs/container/$SLUG-$ARCH/latest | awk '/Total downloads/{getline; print}' | awk -F '<|>' '{print $3}')"
until [ -n "$COUNT" ]; do COUNT="$(curl --connect-timeout 5 -f -s -L https://github.com/Mesteriis/hassio-addons-avm/pkgs/container/$SLUG-$ARCH/latest | awk '/Total downloads/{getline; print}' | awk -F '<|>' '{print $3}')" && sleep 5; ((c++)) && echo "repeat $c" && if [[ "$c" == 10 ]]; then count=0; fi; done
COUNT="${COUNT//,/}"
COUNT2="$COUNT"
echo "$COUNT $ARCH users with $SLUG" && DOWNLOADS="$(( DOWNLOADS + COUNT))"
else COUNT2="-"; fi
if [[ "$(jq '.arch[]' "$f/config.json")" == *"aarch64"* ]]; then
ARCH=aarch64 && COUNT="$(curl --connect-timeout 5 -f -s -L https://github.com/Mesteriis/hassio-addons-avm/pkgs/container/$SLUG-$ARCH/latest | awk '/Total downloads/{getline; print}' | awk -F '<|>' '{print $3}')"
until [ -n "$COUNT" ]; do COUNT="$(curl --connect-timeout 5 -f -s -L https://github.com/Mesteriis/hassio-addons-avm/pkgs/container/$SLUG-$ARCH/latest | awk '/Total downloads/{getline; print}' | awk -F '<|>' '{print $3}')" && sleep 5; ((c++)) && echo "repeat $c" && if [[ "$c" == 10 ]]; then count=0; fi; done
COUNT="${COUNT//,/}"
COUNT3="$COUNT"
echo "$COUNT $ARCH users with $SLUG" && DOWNLOADS="$(( DOWNLOADS + COUNT))"
else COUNT3="-";fi
echo "$SLUG $DOWNLOADS $COUNT1 $COUNT2 $COUNT3" >> "$file"2
# Create line if not existing
if ! grep -q "${SLUG}$" "$file"; then
sed -i "\$a$SLUG" "$file"
# shellcheck disable=SC2046
for i in $(seq $(head -n 1 $file | tr -cd ' \t' | wc -c )); do
echo "$i"
sed -i "/$SLUG/s|^|- |" "$file"
done
fi
# Add data
sed -i "/${SLUG}$/s|^-|$DOWNLOADS|" "$file"
fi
done
# Add total
SLUG=TOTAL
if ! grep -q "$SLUG$" "$file"; then
sed -i "1a$SLUG" "$file"
# shellcheck disable=SC2046
for i in $(seq $(head -n 1 $file | tr -cd ' \t' | wc -c )); do
echo "$i"
sed -i "/$SLUG$/s|^|- |" "$file"
done
fi
DOWNLOADS="$(awk 'FNR > 2 {SUM+=$1}END{print SUM}' Stats)"
sed -i "/$SLUG$/s|^-|$DOWNLOADS|" "$file"
# Sort file
(head -n 2 "$file" && tail -n +3 "$file" | sort -k1 -r -n) > tmp && mv tmp "$file"
sed -i "1i Name Total armv7 amd64 aarch64" "$file"2
sed -i "1a ------------------------------" "$file"2
#TOTAL="$(awk '{SUM+=$2}END{print SUM}' Stats)"
#TOTAL1="$(awk '{SUM+=$2}END{print SUM}' Stats)"
#TOTAL2="$(awk '{SUM+=$2}END{print SUM}' Stats)"
#TOTAL3="$(awk '{SUM+=$2}END{print SUM}' Stats)"
- name: Commit if needed
uses: EndBug/add-and-commit@v9
with:
default_author: github_actions
message : "Github bot : stats updated"
Generate_graphs:
needs: stats_updater
uses: ./.github/workflows/helper_stats_graphs.yaml

1
.mdlrc
View File

@@ -1 +0,0 @@
rules "~MD024"

103
.templates/.README.md Normal file
View File

@@ -0,0 +1,103 @@
# Home assistant add-on: alexbelgium
<!-- markdownlint-disable MD033 -->
[![Donate][donation-badge]](https://www.buymeacoffee.com/alexbelgium)
[![Donate][paypal-badge]](https://www.paypal.com/donate/?hosted_button_id=DZFULJZTP3UQA)
![update-badge](https://img.shields.io/github/last-commit/Mesteriis/hassio-addons-avm?label=last%20update)
[donation-badge]: https://img.shields.io/badge/Buy%20me%20a%20coffee%20(no%20paypal)-%23d32f2f?logo=buy-me-a-coffee&style=flat&logoColor=white
[paypal-badge]: https://img.shields.io/badge/Buy%20me%20a%20coffee%20with%20Paypal-0070BA?logo=paypal&style=flat&logoColor=white
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/9c6cf10bdbba45ecb202d7f579b5be0e)](https://www.codacy.com/gh/Mesteriis/hassio-addons-avm/dashboard?utm_source=github.com&utm_medium=referral&utm_content=Mesteriis/hassio-addons-avm&utm_campaign=Badge_Grade)
[![GitHub Super-Linter](https://img.shields.io/github/actions/workflow/status/Mesteriis/hassio-addons-avm/weekly-supelinter.yaml?label=Lint%20code%20base)](https://github.com/Mesteriis/hassio-addons-avm/actions/workflows/weekly-supelinter.yaml)
[![Builder](https://img.shields.io/github/actions/workflow/status/Mesteriis/hassio-addons-avm/onpush_builder.yaml?label=Builder)](https://github.com/Mesteriis/hassio-addons-avm/actions/workflows/onpush_builder.yaml)
[![Statistics](https://github.com/Mesteriis/hassio-addons-avm/workflows/Generate%20weekly%20stats/badge.svg)](https://github.com/Mesteriis/hassio-addons-avm/actions/workflows/weekly_stats.yaml)
[support-badge]: https://camo.githubusercontent.com/f4dbb995049f512fdc97fcc9e022ac243fa38c408510df9d46c7467d0970d959/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f537570706f72742d7468726561642d677265656e2e737667
_Thanks to everyone having starred my repo! To star it click on the image below, then it will be on top right. Thanks!_
[![Stargazers repo roster for @Mesteriis/hassio-addons-avm](https://reporoster.com/stars/Mesteriis/hassio-addons-avm)](https://github.com/Mesteriis/hassio-addons-avm/stargazers)
_Thanks to all contributors !_
[![contributors](https://contrib.rocks/image?repo=Mesteriis/hassio-addons-avm)](https://github.com/Mesteriis/hassio-addons-avm/graphs/contributors)
## About
Home Assistant allows anyone to create add-on repositories to share their
add-ons for Home Assistant easily. This repository is one of those repositories,
providing extra Home Assistant add-ons for your installation.
The primary goal of this project is to provide you (as a Home Assistant user)
with additional, high quality, add-ons that allow you to take your automated
home to the next level.
## Installation
[![Add repository on my Home Assistant][repository-badge]][repository-url]
If you want to do add the repository manually, please follow the procedure highlighted in the [Home Assistant website](https://home-assistant.io/hassio/installing_third_party_addons). Use the following URL to add this repository: https://github.com/Mesteriis/hassio-addons-avm
## Statistics
### Number of addons
- In the repository : %%STATS_ADDONS%%
- Installed : %%STATS_DOWNLOADS%%
### Top 3
1. %%STATS_ONE%%
2. %%STATS_TWO%%
3. %%STATS_THREE%%
### Architectures used
- %%STATS_AMD64%%
- %%STATS_AARCH64%%
- %%STATS_ARMV7%%
### Total downloads evolution
<img src="https://raw.githubusercontent.com/Mesteriis/hassio-addons-avm/master/.github/stats.png" width=500px>
### Specific downloads evolution
<img src="https://raw.githubusercontent.com/Mesteriis/hassio-addons-avm/master/.github/stats_addons.png" width=500px>
### Stars evolution
<a href="https://star-history.com">
<img src="https://raw.githubusercontent.com/Mesteriis/hassio-addons-avm/master/.github/starsevol.svg" width=500px>
</a>
## Add-ons provided by this repository
%%ADDONS_LIST%%
## Support
Got questions?
You have several options to get them answered:
- The Home Assistant [Community Forum][forum].
- This repository issues list
[aarch64-badge]: https://img.shields.io/badge/aarch64--green.svg?logo=arm
[amd64-badge]: https://img.shields.io/badge/amd64--green.svg?logo=amd
[armv7-badge]: https://img.shields.io/badge/armv7--green.svg?logo=arm
[aarch64no-badge]: https://img.shields.io/badge/aarch64--orange.svg?logo=arm
[amd64no-badge]: https://img.shields.io/badge/amd64--orange.svg?logo=amd
[armv7no-badge]: https://img.shields.io/badge/armv7--orange.svg?logo=arm
[ingress-badge]: https://img.shields.io/badge/-ingress-blueviolet.svg?logo=Ingress
[mariadb-badge]: https://img.shields.io/badge/Service-MariaDB-green.svg?logo=mariadb&logoColor=white
[mqtt-badge]: https://img.shields.io/badge/Service-MQTT-green.svg?logo=chromecast&logoColor=white
[localdisks-badge]: https://img.shields.io/badge/Mounts-localdisks-blue.svg
[smb-badge]: https://img.shields.io/badge/Mounts-networkdisks-blue.svg
[full_access-badge]: https://img.shields.io/badge/Requires-full_access-orange.svg
[forum]: https://community.home-assistant.io/t/alexbelgium-repo-60-addons
[repository-badge]: https://img.shields.io/badge/Add%20repository%20to%20my-Home%20Assistant-41BDF5?logo=home-assistant&style=for-the-badge
[repository-url]: https://my.home-assistant.io/redirect/supervisor_add_addon_repository/?repository_url=https%3A%2F%2Fgithub.com%2Falexbelgium%2Fhassio-addons

View File

@@ -0,0 +1,51 @@
#!/bin/bash
set -e
# If dockerfile failed install manually
##############################
# Automatic modules download #
##############################
if [ -e "/MODULESFILE" ]; then
MODULES=$(</MODULESFILE)
MODULES="${MODULES:-00-banner.sh}"
echo "Executing modules script : $MODULES"
if ! command -v bash >/dev/null 2>/dev/null; then (apt-get update && apt-get install -yqq --no-install-recommends bash || apk add --no-cache bash) >/dev/null; fi &&
if ! command -v curl >/dev/null 2>/dev/null; then (apt-get update && apt-get install -yqq --no-install-recommends curl || apk add --no-cache curl) >/dev/null; fi &&
apt-get update && apt-get install -yqq --no-install-recommends ca-certificates || apk add --no-cache ca-certificates >/dev/null || true &&
mkdir -p /etc/cont-init.d &&
for scripts in $MODULES; do echo "$scripts" && curl -f -L -s -S "https://raw.githubusercontent.com/Mesteriis/hassio-addons-avm/master/.templates/$scripts" -o /etc/cont-init.d/"$scripts" && [ "$(sed -n '/\/bin/p;q' /etc/cont-init.d/"$scripts")" != "" ] || (echo "script failed to install $scripts" && exit 1); done &&
chmod -R 755 /etc/cont-init.d
fi
#######################
# Automatic installer #
#######################
if [ -e "/ENVFILE" ]; then
PACKAGES=$(</ENVFILE)
echo "Executing dependency script with custom elements : $PACKAGES"
if ! command -v bash >/dev/null 2>/dev/null; then (apt-get update && apt-get install -yqq --no-install-recommends bash || apk add --no-cache bash) >/dev/null; fi &&
if ! command -v curl >/dev/null 2>/dev/null; then (apt-get update && apt-get install -yqq --no-install-recommends curl || apk add --no-cache curl) >/dev/null; fi &&
curl -f -L -s -S "https://raw.githubusercontent.com/Mesteriis/hassio-addons-avm/master/.templates/ha_automatic_packages.sh" --output /ha_automatic_packages.sh &&
chmod 777 /ha_automatic_packages.sh &&
eval /./ha_automatic_packages.sh "${PACKAGES:-}" &&
rm /ha_automatic_packages.sh
fi
if [ -e "/MODULESFILE" ] && [ ! -f /ha_entrypoint.sh ]; then
for scripts in $MODULES; do
echo "$scripts : executing"
chown "$(id -u)":"$(id -g)" /etc/cont-init.d/"$scripts"
chmod a+x /etc/cont-init.d/"$scripts"
/./etc/cont-init.d/"$scripts" || echo "/etc/cont-init.d/$scripts: exiting $?"
rm /etc/cont-init.d/"$scripts"
done | tac
fi
#######################
# Correct permissions #
#######################
[ -d /etc/services.d ] && chmod -R 777 /etc/services.d
[ -d /etc/cont-init.d ] && chmod -R 777 /etc/cont-init.d

61
.templates/00-banner.sh Executable file
View File

@@ -0,0 +1,61 @@
#!/usr/bin/with-contenv bashio
# shellcheck shell=bash
set -e
# ==============================================================================
# Displays a simple add-on banner on startup
# ==============================================================================
if bashio::supervisor.ping; then
bashio::log.blue \
'-----------------------------------------------------------'
bashio::log.blue " Add-on: $(bashio::addon.name)"
bashio::log.blue " $(bashio::addon.description)"
bashio::log.blue \
'-----------------------------------------------------------'
bashio::log.blue " Add-on version: $(bashio::addon.version)"
if bashio::var.true "$(bashio::addon.update_available)"; then
bashio::log.magenta ' There is an update available for this add-on!'
bashio::log.magenta \
" Latest add-on version: $(bashio::addon.version_latest)"
bashio::log.magenta ' Please consider upgrading as soon as possible.'
else
bashio::log.green ' You are running the latest version of this add-on.'
fi
bashio::log.blue " System: $(bashio::info.operating_system)" \
" ($(bashio::info.arch) / $(bashio::info.machine))"
bashio::log.blue " Home Assistant Core: $(bashio::info.homeassistant)"
bashio::log.blue " Home Assistant Supervisor: $(bashio::info.supervisor)"
bashio::log.blue \
'-----------------------------------------------------------'
bashio::log.blue \
' Please, share the above information when looking for help'
bashio::log.blue \
' or support in, e.g., GitHub, forums'
bashio::log.blue \
'-----------------------------------------------------------'
bashio::log.green \
' Provided by: https://github.com/Mesteriis/hassio-addons-avm '
bashio::log.blue \
'-----------------------------------------------------------'
fi
# ==============================================================================
# Global actions for all addons
# ==============================================================================
if bashio::config.has_value "PUID" && bashio::config.has_value "PGID"; then
bashio::log.green \
' Defining permissions for main user : '
PUID="$(bashio::config "PUID")"
PGID="$(bashio::config "PGID")"
bashio::log.blue "User UID: $PUID"
bashio::log.blue "User GID : $PGID"
id -u abc &>/dev/null || usermod -o -u "$PUID" abc &>/dev/null || true
id -g abc &>/dev/null || groupmod -o -g "$PGID" abc &>/dev/null || true
bashio::log.blue \
'-----------------------------------------------------------'
fi
# Clean bashrc file
if [ -f ~/.bashrc ]; then rm ~/.bashrc; fi

View File

@@ -0,0 +1,8 @@
#!/bin/bash
# Color comments
#! Red
#? Question
#// Done
#todo To do
#* Green

19
.templates/00-deprecated.sh Executable file
View File

@@ -0,0 +1,19 @@
#!/usr/bin/with-contenv bashio
# shellcheck shell=bash
set -e
# ==============================================================================
# Displays a simple add-on banner on startup
# ==============================================================================
echo ""
bashio::log.yellow "####################"
bashio::log.yellow "# ADDON deprecated #"
bashio::log.yellow "####################"
echo ""
bashio::log.yellow "This addon is now supported in the official HA community repository. You should migrate your data as soon as possible! This addon will not be supported and updates might stop in the future."
bashio::log.yellow "You'll likely get better support as the official community is supported by the HA devs ! If some features from the official add-on are missing you should raise a request on the ha community add-ons repo"
bashio::log.yellow "Thanks for all users over the years !"
echo ""
sleep 5

101
.templates/00-global_var.sh Executable file
View File

@@ -0,0 +1,101 @@
#!/usr/bin/with-contenv bashio
# shellcheck shell=bash
set -e
###################################
# Export all addon options as env #
###################################
# For all keys in options.json
JSONSOURCE="/data/options.json"
# Define secrets location
if [ -f /homeassistant/secrets.yaml ]; then
SECRETSOURCE="/homeassistant/secrets.yaml"
elif [ -f /config/secrets.yaml ]; then
SECRETSOURCE="/config/secrets.yaml"
else
SECRETSOURCE="false"
fi
# Export keys as env variables
# echo "All addon options were exported as variables"
mapfile -t arr < <(jq -r 'keys[]' "${JSONSOURCE}")
for KEYS in "${arr[@]}"; do
# export key
VALUE=$(jq ."$KEYS" "${JSONSOURCE}")
# Check if the value is an array
if [[ "$VALUE" == \[* ]]; then
bashio::log.warning "$VALUE is an array, skipping"
else
# Continue for single values
VALUE="${VALUE//[\"\']/}"
line="${KEYS}='${VALUE}'"
# Check if secret
if [[ "${line}" == *"!secret "* ]]; then
echo "secret detected"
# Get argument
secret=${line#*secret }
# Remove trailing ' or "
secret="${secret%[\"\']}"
# Stop if secret file not mounted
if [[ "$SECRETSOURCE" == "false" ]]; then
bashio::log.warning "Homeassistant config not mounted, secrets are not supported"
continue
fi
# Check if single match
secretnum=$(sed -n "/$secret:/=" "$SECRETSOURCE" )
[[ "$secretnum" == *' '* ]] && bashio::exit.nok "There are multiple matches for your password name. Please check your secrets.yaml file"
# Get text
secret=$(sed -n "/$secret:/p" "$SECRETSOURCE" )
secret=${secret#*: }
line="${line%%=*}='$secret'"
VALUE="$secret"
fi
# text
if bashio::config.false "verbose" || [[ "${KEYS}" == *"PASS"* ]]; then
bashio::log.blue "${KEYS}=******"
else
bashio::log.blue "$line"
fi
######################################
# Export the variable to run scripts #
######################################
# shellcheck disable=SC2163
export "$line"
# export to python
if command -v "python3" &>/dev/null ; then
[ ! -f /env.py ] && echo "import os" > /env.py
# Escape \
VALUEPY="${VALUE//\\/\\\\}"
# Avoid " and '
VALUEPY="${VALUEPY//[\"\']/}"
echo "os.environ['${KEYS}'] = '$VALUEPY'" >> /env.py
python3 /env.py
fi
# set .env
echo "$line" >> /.env || true
# set /etc/environment
mkdir -p /etc
echo "$line" >> /etc/environment
# For non s6
if cat /etc/services.d/*/*run* &>/dev/null; then sed -i "1a export $line" /etc/services.d/*/*run* 2>/dev/null; fi
if cat /etc/cont-init.d/*run* &>/dev/null; then sed -i "1a export $line" /etc/cont-init.d/*run* 2>/dev/null; fi
# For s6
if [ -d /var/run/s6/container_environment ]; then printf "%s" "${VALUE}" > /var/run/s6/container_environment/"${KEYS}"; fi
echo "export ${KEYS}='${VALUE}'" >> ~/.bashrc
fi
done
################
# Set timezone #
################
set +e
if [ -n "$TZ" ] && [ -f /etc/localtime ]; then
if [ -f /usr/share/zoneinfo/"$TZ" ]; then
echo "Timezone set from $(cat /etc/timezone) to $TZ"
ln -snf /usr/share/zoneinfo/"$TZ" /etc/localtime && echo "$TZ" >/etc/timezone
fi
fi

103
.templates/00-local_mounts.sh Executable file
View File

@@ -0,0 +1,103 @@
#!/usr/bin/with-contenv bashio
# shellcheck shell=bash
set -e
######################
# MOUNT LOCAL SHARES #
######################
# Mount local Share if configured
if bashio::config.has_value 'localdisks'; then
# Available devices
blkid | awk '{print substr($1, 0, length($1) - 1)}' | awk -F'/' '{print $NF}' > availabledisks
echo "NAME" >> availabledisks
## List available Disk with Labels and Id
bashio::log.blue "---------------------------------------------------"
bashio::log.info "Available Disks for mounting :"
lsblk -o name,label,size,fstype,ro | awk '$4 != "" { print $0 }' | grep -f availabledisks
bashio::log.blue "---------------------------------------------------"
rm availabledisks
# Show support fs https://github.com/dianlight/hassio-addons/blob/2e903184254617ac2484fe7c03a6e33e6987151c/sambanas/rootfs/etc/s6-overlay/s6-rc.d/init-automount/run#L106
fstypessupport=$(grep -v nodev </proc/filesystems | awk '{$1=" "$1}1' | tr -d '\n\t')
bashio::log.green "Supported fs : ${fstypessupport}"
bashio::log.green "Inspired from : github.com/dianlight"
bashio::log.blue "---------------------------------------------------"
MOREDISKS=$(bashio::config 'localdisks')
echo "Local Disks mounting..."
# Separate comma separated values
# shellcheck disable=SC2086
for disk in ${MOREDISKS//,/ }; do
# Remove text until last slash
disk="${disk##*/}"
# Function to check what is the type of device
if [ -e /dev/"$disk" ]; then
echo "... $disk is a physical device"
devpath=/dev
elif [ -e /dev/disk/by-uuid/"$disk" ] || lsblk -o UUID | grep -q "$disk"; then
echo "... $disk is a device by UUID"
devpath=/dev/disk/by-uuid
elif [ -e /dev/disk/by-label/"$disk" ] || lsblk -o LABEL | grep -q "$disk"; then
echo "... $disk is a device by label"
devpath=/dev/disk/by-label
else
bashio::log.fatal "$disk does not match any known physical device, UUID, or label. "
continue
fi
# Creates dir
mkdir -p /mnt/"$disk"
if bashio::config.has_value 'PUID' && bashio::config.has_value 'PGID'; then
PUID="$(bashio::config 'PUID')"
PGID="$(bashio::config 'PGID')"
chown "$PUID:$PGID" /mnt/"$disk"
fi
# Check FS type and set relative options (thanks @https://github.com/dianlight/hassio-addons)
fstype=$(lsblk "$devpath"/"$disk" -no fstype)
options="nosuid,relatime,noexec"
type="auto"
# Check if supported
if [[ "${fstypessupport}" != *"${fstype}"* ]]; then
bashio::log.fatal : "${fstype} type for ${disk} is not supported"
break
fi
# Mount drive
bashio::log.info "Mounting ${disk} of type ${fstype}"
case "$fstype" in
exfat | vfat | msdos)
bashio::log.warning "${fstype} permissions and ACL don't works and this is an EXPERIMENTAL support"
options="${options},umask=000"
;;
ntfs)
bashio::log.warning "${fstype} is an EXPERIMENTAL support"
options="${options},umask=000"
type="ntfs"
;;
squashfs)
bashio::log.warning "${fstype} is an EXPERIMENTAL support"
options="loop"
type="squashfs"
;;
esac
# Legacy mounting : mount to share if still exists (avoid breaking changes)
dirpath="/mnt"
if [ -d /share/"$disk" ]; then dirpath="/share"; fi
# shellcheck disable=SC2015
mount -t $type "$devpath"/"$disk" "$dirpath"/"$disk" -o $options && bashio::log.info "Success! $disk mounted to /mnt/$disk" || \
(bashio::log.fatal "Unable to mount local drives! Please check the name."
rmdir /mnt/"$disk"
bashio::addon.stop)
done
fi

276
.templates/00-smb_mounts.sh Executable file
View File

@@ -0,0 +1,276 @@
#!/usr/bin/with-contenv bashio
# shellcheck shell=bash
# shellcheck disable=
set -e
####################
# DEFINE FUNCTIONS #
####################
test_mount () {
# Set initial test
MOUNTED=false
ERROR_MOUNT=false
# Exit if not mounted
if ! mountpoint -q /mnt/"$diskname"; then
return 0
fi
# Exit if can't write
# shellcheck disable=SC2015
mkdir "/mnt/$diskname/testaze" && touch "/mnt/$diskname/testaze/testaze" && rm -r "/mnt/$diskname/testaze" || ERROR_MOUNT=true
if [[ "$ERROR_MOUNT" == "true" ]]; then
# Test write permissions
if [[ "$MOUNTOPTIONS" == *"noserverino"* ]]; then
bashio::log.fatal "Disk is mounted, however unable to write in the shared disk. Please check UID/GID for permissions, and if the share is rw"
else
MOUNTOPTIONS="$MOUNTOPTIONS,noserverino"
echo "... testing with noserverino"
mount_drive "$MOUNTOPTIONS"
return 0
fi
fi
# Set correctly mounted bit
MOUNTED=true
return 0
}
mount_drive () {
# Define options
MOUNTED=true
MOUNTOPTIONS="$1"
# Try mounting
mount -t cifs -o "$MOUNTOPTIONS" "$disk" /mnt/"$diskname" 2>ERRORCODE || MOUNTED=false
# Test if succesful
if [[ "$MOUNTED" == "true" ]]; then
# shellcheck disable=SC2015
test_mount
fi
}
####################
# MOUNT SMB SHARES #
####################
if bashio::config.has_value 'networkdisks'; then
# Alert message that it is a new code
if [[ "$(date +"%Y%m%d")" -lt "20240201" ]]; then
bashio::log.warning "------------------------"
bashio::log.warning "This is a new code, please report any issues on https://github.com/Mesteriis/hassio-addons-avm"
bashio::log.warning "------------------------"
fi
echo 'Mounting smb share(s)...'
####################
# Define variables #
####################
# Set variables
MOREDISKS=$(bashio::config 'networkdisks')
USERNAME=$(bashio::config 'cifsusername')
PASSWORD=$(bashio::config 'cifspassword')
SMBVERS=""
SECVERS=""
CHARSET=",iocharset=utf8"
# Clean data
MOREDISKS=${MOREDISKS// \/\//,\/\/}
MOREDISKS=${MOREDISKS//, /,}
MOREDISKS=${MOREDISKS// /"\040"}
# Is domain set
DOMAIN=""
DOMAINCLIENT=""
if bashio::config.has_value 'cifsdomain'; then
echo "... using domain $(bashio::config 'cifsdomain')"
DOMAIN=",domain=$(bashio::config 'cifsdomain')"
DOMAINCLIENT="--workgroup=$(bashio::config 'cifsdomain')"
fi
# Is UID/GID set
PUID=",uid=$(id -u)"
PGID=",gid=$(id -g)"
if bashio::config.has_value 'PUID' && bashio::config.has_value 'PGID'; then
echo "... using PUID $(bashio::config 'PUID') and PGID $(bashio::config 'PGID')"
PUID=",uid=$(bashio::config 'PUID')"
PGID=",gid=$(bashio::config 'PGID')"
fi
##################
# Mounting disks #
##################
# shellcheck disable=SC2086
for disk in ${MOREDISKS//,/ }; do # Separate comma separated values
# Clean name of network share
# shellcheck disable=SC2116,SC2001
disk=$(echo $disk | sed "s,/$,,") # Remove / at end of name
disk="${disk//"\040"/ }" #replace \040 with
diskname="${disk//\\//}" #replace \ with /
diskname="${diskname##*/}" # Get only last part of the name
MOUNTED=false
# Start
echo "... mounting $disk"
# Data validation
if [[ ! "$disk" =~ ^.*+[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+[/]+.*+$ ]]; then
bashio::log.fatal "...... the structure of your \"networkdisks\" option : \"$disk\" doesn't seem correct, please use a structure like //123.12.12.12/sharedfolder,//123.12.12.12/sharedfolder2. If you don't use it, you can simply remove the text, this will avoid this error message in the future."
touch ERRORCODE
continue
fi
# Prepare mount point
mkdir -p /mnt/"$diskname"
chown root:root /mnt/"$diskname"
# Quickly try to mount with defaults
mount_drive "rw,file_mode=0775,dir_mode=0775,username=${USERNAME},password=${PASSWORD},nobrl${SMBVERS}${SECVERS}${PUID}${PGID}${CHARSET}${DOMAIN}"
# Deeper analysis if failed
if [ "$MOUNTED" = false ]; then
# Extract ip part of server for further manipulation
server="$(echo "$disk" | grep -E -o "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+")"
# Does server exists
output="$(nmap -F $server -T5 -oG -)"
if ! echo "$output" | grep 445/open &>/dev/null; then
if echo "$output" | grep /open &>/dev/null; then
bashio::log.fatal "...... $server is reachable but SMB port not opened, stopping script"
touch ERRORCODE
continue
else
bashio::log.fatal "...... fatal : $server not reachable, is it correct"
touch ERRORCODE
continue
fi
else
echo "...... $server is confirmed reachable"
fi
# Are credentials correct
OUTPUT="$(smbclient -t 2 -L "$disk" -U "$USERNAME"%"$PASSWORD" -c "exit" $DOMAINCLIENT 2>&1 || true)"
if echo "$OUTPUT" | grep -q "LOGON_FAILURE"; then
bashio::log.fatal "...... incorrect Username, Password, or Domain! Script will stop."
touch ERRORCODE
# Should there be a workgroup
if ! smbclient -t 2 -L $disk -N $DOMAINCLIENT -c "exit" &>/dev/null; then
bashio::log.fatal "...... perhaps a workgroup must be specified"
touch ERRORCODE
fi
continue
elif echo "$OUTPUT" | grep -q "tree connect failed" || echo "$OUTPUT" | grep -q "NT_STATUS_CONNECTION_DISCONNECTED"; then
echo "... testing path"
bashio::log.fatal "...... invalid or inaccessible SMB path. Script will stop."
touch ERRORCODE
continue
elif ! echo "$OUTPUT" | grep -q "Disk"; then
echo "... testing path"
bashio::log.fatal "...... no shares found. Invalid or inaccessible SMB path?"
else
echo "...... credentials are valid"
fi
# Extracting SMB versions and normalize output
# shellcheck disable=SC2210,SC2094
SMBVERS="$(nmap --script smb-protocols "$server" -p 445 2>1 | awk '/ [0-9]/' | awk '{print $NF}' | cut -c -3 | sort -V | tail -n 1 || true)"
# Avoid :
SMBVERS="${SMBVERS/:/.}"
# Manage output
if [ -n "$SMBVERS" ]; then
case $SMBVERS in
"202"|"200"|"20")
SMBVERS="2.0"
;;
21)
SMBVERS="2.1"
;;
302)
SMBVERS="3.02"
;;
311)
SMBVERS="3.1.1"
;;
"3.1")
echo "SMB 3.1 detected, converting to 3.0"
SMBVERS="3.0"
;;
esac
echo "...... SMB version detected : $SMBVERS"
SMBVERS=",vers=$SMBVERS"
elif smbclient -t 2 -L "$server" -m NT1 -N $DOMAINCLIENT &>/dev/null; then
echo "...... SMB version : only SMBv1 is supported, this can lead to issues"
SECVERS=",sec=ntlm"
SMBVERS=",vers=1.0"
else
echo "...... SMB version : couldn't detect, default used"
SMBVERS=""
fi
# Test with different security versions
#######################################
for SECVERS in "$SECVERS" ",sec=ntlmv2" ",sec=ntlmssp" ",sec=ntlmsspi" ",sec=krb5i" ",sec=krb5" ",sec=ntlm" ",sec=ntlmv2i"; do
if [ "$MOUNTED" = false ]; then
mount_drive "rw,file_mode=0775,dir_mode=0775,username=${USERNAME},password=${PASSWORD},nobrl${SMBVERS}${SECVERS}${PUID}${PGID}${CHARSET}${DOMAIN}"
fi
done
fi
# Messages
if [ "$MOUNTED" = true ]; then
bashio::log.info "...... $disk successfully mounted to /mnt/$diskname with options ${MOUNTOPTIONS/$PASSWORD/XXXXXXXXXX}"
# Remove errorcode
if [ -f ERRORCODE ]; then
rm ERRORCODE
fi
# Alert if smbv1
if [[ "$MOUNTOPTIONS" == *"1.0"* ]]; then
bashio::log.warning ""
bashio::log.warning "Your smb system requires smbv1. This is an obsolete protocol. Please correct this to prevent issues."
bashio::log.warning ""
fi
else
# Mounting failed messages
bashio::log.fatal "Error, unable to mount $disk to /mnt/$diskname with username $USERNAME, $PASSWORD. Please check your remote share path, username, password, domain, try putting 0 in UID and GID"
bashio::log.fatal "Here is some debugging info :"
# Provide debugging info
smbclient -t 2 -L $disk -U "$USERNAME%$PASSWORD" -c "exit"
# Error code
SMBVERS=""
SECVERS=""
PUID=""
PGID=""
CHARSET=""
mount_drive "rw,file_mode=0775,dir_mode=0775,username=${USERNAME},password=${PASSWORD},nobrl${SMBVERS}${SECVERS}${PUID}${PGID}${CHARSET}${DOMAIN}"
bashio::log.fatal "Error read : $(<ERRORCODE), addon will stop in 1 min"
# clean folder
umount "/mnt/$diskname" 2>/dev/null || true
rmdir "/mnt/$diskname" || true
# Stop addon
bashio::addon.stop
fi
done
fi

200
.templates/01-config_yaml.sh Executable file
View File

@@ -0,0 +1,200 @@
#!/usr/bin/with-contenv bashio
# shellcheck shell=bash
# shellcheck disable=SC2155,SC1087,SC2163,SC2116,SC2086
set -e
##################
# INITIALIZATION #
##################
# Exit if /config is not mounted
if [ ! -d /config ]; then
exit 0
fi
# Define slug
slug="${HOSTNAME}"
# Check type of config folder
if [ ! -f /config/configuration.yaml ] && [ ! -f /config/configuration.json ]; then
# New config location
CONFIGLOCATION="/config"
CONFIGFILEBROWSER="/addon_configs/$slug/config.yaml"
else
# Legacy config location
slug="${HOSTNAME#*-}"
CONFIGLOCATION="/config/addons_config/${slug}"
CONFIGFILEBROWSER="/homeassistant/addons_config/$slug/config.yaml"
fi
# Default location
mkdir -p "$CONFIGLOCATION" || true
CONFIGSOURCE="$CONFIGLOCATION"/config.yaml
# Is there a custom path
if bashio::config.has_value 'CONFIG_LOCATION'; then
CONFIGSOURCE=$(bashio::config "CONFIG_LOCATION")
# If does not end by config.yaml, remove trailing slash and add config.yaml
if [[ "$CONFIGSOURCE" != *".yaml" ]]; then
CONFIGSOURCE="${CONFIGSOURCE%/}"/config.yaml
fi
# Check if config is located in an acceptable location
LOCATIONOK=""
for location in "/share" "/config" "/data"; do
if [[ "$CONFIGSOURCE" == "$location"* ]]; then
LOCATIONOK=true
fi
done
if [ -z "$LOCATIONOK" ]; then
bashio::log.red "Watch-out : your CONFIG_LOCATION values can only be set in /share, /config or /data (internal to addon). It will be reset to the default location : $CONFIGLOCATION/config.yaml"
CONFIGSOURCE="$CONFIGLOCATION"/config.yaml
fi
fi
# Migrate if needed
if [[ "$CONFIGLOCATION" == "/config" ]]; then
# Migrate file
if [ -f "/homeassistant/addons_config/${slug}/config.yaml" ]; then
echo "Migrating config.yaml to new config location"
mv /homeassistant/addons_config/"${slug}"/config.yaml /config/config.yaml
fi
# Migrate option
if [[ "$(bashio::config "CONFIG_LOCATION")" == "/config/addons_config"* ]] && [ -f /config/config.yaml ]; then
bashio::addon.option "CONFIG_LOCATION" "/config/config.yaml"
CONFIGSOURCE="/config/config.yaml"
fi
fi
if [[ "$CONFIGSOURCE" != *".yaml" ]]; then
bashio::log.error "Something is going wrong in the config location, quitting"
fi
# Permissions
if [[ "$CONFIGSOURCE" == *".yaml" ]]; then
echo "Setting permissions for the config.yaml directory"
mkdir -p "$(dirname "${CONFIGSOURCE}")"
chmod -R 755 "$(dirname "${CONFIGSOURCE}")" 2>/dev/null
fi
####################
# LOAD CONFIG.YAML #
####################
echo ""
bashio::log.green "Load environment variables from $CONFIGSOURCE if existing"
if [[ "$CONFIGSOURCE" == "/config"* ]]; then
bashio::log.green "If accessing the file with filebrowser it should be mapped to $CONFIGFILEBROWSER"
else
bashio::log.green "If accessing the file with filebrowser it should be mapped to $CONFIGSOURCE"
fi
bashio::log.green "---------------------------------------------------------"
bashio::log.green "Wiki here on how to use : github.com/Mesteriis/hassio-addons-avm/wiki/Addons-feature-:-add-env-variables"
echo ""
# Check if config file is there, or create one from template
if [ ! -f "$CONFIGSOURCE" ]; then
echo "... no config file, creating one from template. Please customize the file in $CONFIGSOURCE before restarting."
# Create folder
mkdir -p "$(dirname "${CONFIGSOURCE}")"
# Placing template in config
if [ -f /templates/config.yaml ]; then
# Use available template
cp /templates/config.yaml "$(dirname "${CONFIGSOURCE}")"
else
# Download template
TEMPLATESOURCE="https://raw.githubusercontent.com/Mesteriis/hassio-addons-avm/master/.templates/config.template"
curl -f -L -s -S "$TEMPLATESOURCE" --output "$CONFIGSOURCE"
fi
fi
# Check if there are lines to read
cp "$CONFIGSOURCE" /tempenv
sed -i '/^#/d' /tempenv
sed -i '/^ /d' /tempenv
sed -i '/^$/d' /tempenv
# Exit if empty
if [ ! -s /tempenv ]; then
bashio::log.green "... no env variables found, exiting"
exit 0
fi
rm /tempenv
# Check if yaml is valid
EXIT_CODE=0
yamllint -d relaxed "$CONFIGSOURCE" &>ERROR || EXIT_CODE=$?
if [ "$EXIT_CODE" != 0 ]; then
cat ERROR
bashio::log.yellow "... config file has an invalid yaml format. Please check the file in $CONFIGSOURCE. Errors list above."
fi
# Export all yaml entries as env variables
# Helper function
function parse_yaml {
local prefix=$2 || local prefix=""
local s='[[:space:]]*' w='[a-zA-Z0-9_]*' fs=$(echo @ | tr @ '\034')
sed -ne "s|^\($s\):|\1|" \
-e "s| #.*$||g" \
-e "s|#.*$||g" \
-e "s|^\($s\)\($w\)$s:$s[\"']\(.*\)[\"']$s\$|\1$fs\2$fs\3|p" \
-e "s|^\($s\)\($w\)$s:$s\(.*\)$s\$|\1$fs\2$fs\3|p" $1 |
awk -F$fs '{
indent = length($1)/2;
vname[indent] = $2;
for (i in vname) {if (i > indent) {delete vname[i]}}
if (length($3) > 0) {
vn=""; for (i=0; i<indent; i++) {vn=(vn)(vname[i])("_")}
printf("%s%s%s=\"%s\"\n", "'$prefix'",vn, $2, $3);
}
}'
}
# Get list of parameters in a file
parse_yaml "$CONFIGSOURCE" "" >/tmpfile
# Escape dollars
sed -i 's|$.|\$|g' /tmpfile
while IFS= read -r line; do
# Clean output
line="${line//[\"\']/}"
# Check if secret
if [[ "${line}" == *'!secret '* ]]; then
echo "secret detected"
secret=${line#*secret }
# Check if single match
secretnum=$(sed -n "/$secret:/=" /config/secrets.yaml)
[[ $(echo $secretnum) == *' '* ]] && bashio::exit.nok "There are multiple matches for your password name. Please check your secrets.yaml file"
# Get text
secret=$(sed -n "/$secret:/p" /config/secrets.yaml)
secret=${secret#*: }
line="${line%%=*}='$secret'"
fi
# Data validation
if [[ "$line" =~ ^.+[=].+$ ]]; then
# extract keys and values
KEYS="${line%%=*}"
VALUE="${line#*=}"
line="${KEYS}='${VALUE}'"
export "$line"
# export to python
if command -v "python3" &>/dev/null; then
[ ! -f /env.py ] && echo "import os" > /env.py
echo "os.environ['${KEYS}'] = '${VALUE//[\"\']/}'" >> /env.py
python3 /env.py
fi
# set .env
if [ -f /.env ]; then echo "$line" >> /.env; fi
mkdir -p /etc
echo "$line" >> /etc/environment
# Export to scripts
if cat /etc/services.d/*/*run* &>/dev/null; then sed -i "1a export $line" /etc/services.d/*/*run* 2>/dev/null; fi
if cat /etc/cont-init.d/*run* &>/dev/null; then sed -i "1a export $line" /etc/cont-init.d/*run* 2>/dev/null; fi
# For s6
if [ -d /var/run/s6/container_environment ]; then printf "%s" "${VALUE}" > /var/run/s6/container_environment/"${KEYS}"; fi
echo "export $line" >> ~/.bashrc
# Show in log
if ! bashio::config.false "verbose"; then bashio::log.blue "$line"; fi
else
bashio::log.red "$line does not follow the correct structure. Please check your yaml file."
fi
done <"/tmpfile"

66
.templates/01-custom_script.sh Executable file
View File

@@ -0,0 +1,66 @@
#!/usr/bin/with-contenv bashio
# shellcheck shell=bash
set -e
##################
# INITIALIZATION #
##################
# Exit if /config is not mounted
if [ ! -d /config ]; then
exit 0
fi
# Define slug
slug="${HOSTNAME}"
# Check type of config folder
if [ ! -f /config/configuration.yaml ] && [ ! -f /config/configuration.json ]; then
# New config location
CONFIGLOCATION="/config"
CONFIGFILEBROWSER="/addon_configs/$slug/${HOSTNAME#*-}.sh"
else
# Legacy config location
slug="${HOSTNAME#*-}"
CONFIGLOCATION="/config/addons_autoscripts"
CONFIGFILEBROWSER="/homeassistant/addons_config/${slug}/${slug}.sh"
fi
# Default location
mkdir -p "$CONFIGLOCATION" || true
CONFIGSOURCE="$CONFIGLOCATION/${HOSTNAME#*-}.sh"
bashio::log.green "Execute $CONFIGFILEBROWSER if existing"
bashio::log.green "Wiki here : github.com/Mesteriis/hassio-addons-avm/wiki/Add-ons-feature-:-customisation"
# Download template if no script found and exit
if [ ! -f "$CONFIGSOURCE" ]; then
TEMPLATESOURCE="https://raw.githubusercontent.com/Mesteriis/hassio-addons-avm/master/.templates/script.template"
curl -f -L -s -S "$TEMPLATESOURCE" --output "$CONFIGSOURCE" || true
exit 0
fi
# Convert scripts to linux
dos2unix "$CONFIGSOURCE" &>/dev/null || true
chmod +x "$CONFIGSOURCE"
# Get current shebang, if not available use another
currentshebang="$(sed -n '1{s/^#![[:blank:]]*//p;q}' "$CONFIGSOURCE")"
if [ ! -f "${currentshebang%% *}" ]; then
for shebang in "/command/with-contenv bashio" "/usr/bin/env bashio" "/usr/bin/bashio" "/bin/bash" "/bin/sh"; do if [ -f "${shebang%% *}" ]; then break; fi; done
sed -i "s|$currentshebang|$shebang|g" "$CONFIGSOURCE"
fi
# Check if there is actual commands
while IFS= read -r line
do
# Remove leading and trailing whitespaces
line="$(echo "$line" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
# Check if line is not empty and does not start with #
if [[ -n "$line" ]] && [[ ! "$line" =~ ^# ]]; then
bashio::log.green "... script found, executing"
/."$CONFIGSOURCE"
exit 0
fi
done < "$CONFIGSOURCE"

46
.templates/19-json_repair.sh Executable file
View File

@@ -0,0 +1,46 @@
#!/usr/bin/with-contenv bashio
# shellcheck shell=bash
set -e
# shellchek disable=SC2015
JSONTOCHECK='/config/transmission/settings.json'
JSONSOURCE='/defaults/settings.json'
# If json already exists
if [ -f "${JSONTOCHECK}" ]; then
# Variables
echo "Checking settings.json format"
# Check if json file valid or not
jq . -S "${JSONTOCHECK}" &>/dev/null && ERROR=false || ERROR=true
if [ "$ERROR" = true ]; then
bashio::log.fatal "Settings.json structure is abnormal, restoring options from scratch. Your old file is renamed as settings.json_old"
mv "${JSONSOURCE}" "${JSONSOURCE}"_old
cp "${JSONSOURCE}" "${JSONTOCHECK}"
exit 0
fi
# Get the default keys from the original file
mapfile -t arr < <(jq -r 'keys[]' "${JSONSOURCE}")
# Check if all keys are still there, or add them
# spellcheck disable=SC2068
for KEYS in "${arr[@]}"; do
# Check if key exists
KEYSTHERE=$(jq "has(\"${KEYS}\")" "${JSONTOCHECK}")
if [ "$KEYSTHERE" != "true" ]; then
#Fetch initial value
JSONSOURCEVALUE=$(jq -r ".\"$KEYS\"" "${JSONSOURCE}")
#Add key
sed -i "3 i\"${KEYS}\": \"${JSONSOURCEVALUE}\"," "${JSONTOCHECK}"
# Message
bashio::log.warning "${KEYS} was missing from your settings.json, it was added with the default value ${JSONSOURCEVALUE}"
fi
done
# Show structure in a nice way
jq . -S "${JSONTOCHECK}" | cat >temp.json && mv temp.json "${JSONTOCHECK}"
# Message
bashio::log.info "Your settings.json was checked and seems perfectly normal!"
fi

View File

@@ -0,0 +1,35 @@
#!/usr/bin/with-contenv bashio
# shellcheck shell=bash
set -e
# Disables ingress and sets a default index
# Disable Ingress
if bashio::config.true "ingress_disabled"; then
bashio::log.warning "Ingress is disabled. You'll need to connect using ip:port"
# Adapt ingress.conf
sed -i "/root/d" /etc/nginx/servers/ingress.conf
sed -i "/proxy_pass/i root /etc;" /etc/nginx/servers/ingress.conf
sed -i "/proxy_pass/i try_files '' /ingress.html =404;" /etc/nginx/servers/ingress.conf
sed -i "/proxy_pass/d" /etc/nginx/servers/ingress.conf
# Create index.html
touch /etc/ingress.html
cat > /etc/ingress.html << EOF
<!DOCTYPE html>
<html>
<head>
<title>Ingress is disabled!</title>
</head>
<body>
<div class="your_class"></div>
<p style="background-color:black;color:yellow">
Ingress was disabled by the user. Please connect using ip:port or
re-enable in the addons options.
</p>
</body>
</html>
EOF
fi

44
.templates/90-dns_set.sh Executable file
View File

@@ -0,0 +1,44 @@
#!/usr/bin/with-contenv bashio
# shellcheck shell=bash
set -e
###############
# DNS SETTING #
###############
# Avoid usage of local dns such as adguard home or pihole\n"
if bashio::config.has_value 'DNS_server'; then
# Define variables
DNSSERVER=$(bashio::config 'DNS_server')
DNS=""
DNSLIST=""
# Get DNS servers
# shellcheck disable=SC2086
for server in ${DNSSERVER//,/ }; do # Separate comma separated values
# Only add DNS if successful
if ping -c 1 "$server" &> /dev/null
then
DNS="${DNS}nameserver $server\n"
DNSLIST="$server $DNSLIST"
else
bashio::log.warning "DNS $server was requested but can't be pinged. It won't be used"
fi
done
# Only add DNS if there are DNS set
# shellcheck disable=SC2236
if [[ ! -z "$DNS" ]]; then
# Write resolv.conf
# shellcheck disable=SC2059
printf "${DNS}" >/etc/resolv.conf
chmod 644 /etc/resolv.conf
bashio::log.info "DNS SERVERS set to $DNSLIST"
else
bashio::log.warning "No valid DNS were found. Using default router (or HA) dns servers."
fi
else
bashio::log.info "DNS Servers option empty. Using default router (or HA) dns servers."
fi

14
.templates/91-silent.sh Executable file
View File

@@ -0,0 +1,14 @@
#!/usr/bin/with-contenv bashio
# shellcheck shell=bash
set -e
###############
# SILENT MODE #
###############
if bashio::config.true 'silent'; then
APPEND=' > /dev/null'
sed -i '$s|$|'"$APPEND"'|' /etc/services.d/*/run &>/dev/null || true
sed -i '$s|$|'"$APPEND"'|' /etc/cont-init.d/*/*run* &>/dev/null || true
bashio::log.info 'Silent mode activated, all logs from emby server are hidden. Disable this option if you need to troubleshoot the addon.'
fi

View File

@@ -0,0 +1,172 @@
#!/usr/bin/env bashio
set -e
if bashio::config.has_value "graphic_driver"; then
# Origin : https://github.com/wumingjieno1/photoprism-test/blob/main/scripts/dist/install-gpu.sh
# abort if not executed as root
if [[ $(id -u) != "0" ]]; then
# shellcheck disable=SC2128
bashio::log.fatal "Error: Run $(basename "${BASH_SOURCE}") as root" 1>&2
exit 1
fi
# Get installer type
if [ -f /usr/bin/apt ]; then
bashio::log.info "... Distribution detected : Debian/Ubuntu"
apt-get install -yqq software-properties-common >/dev/null
add-apt-repository ppa:kisak/kisak-mesa >/dev/null
apt-get update >/dev/null
apt-get install -yqq mesa
elif [ -f /usr/bin/apk ]; then
bashio::log.info "... Distribution detected : Alpine"
fi
# Detect GPU
# shellcheck disable=SC2207
GPU_DETECTED=($(lshw -c display -json 2>/dev/null | jq -r '.[].configuration.driver'))
bashio::log.info "... GPU detected: ${GPU_DETECTED[*]}"
graphic_driver=""
# Get arch type
BUILD_ARCH="$(uname -m)"
case "$BUILD_ARCH" in
amd64 | AMD64 | x86_64 | x86-64)
BUILD_ARCH=amd64
;;
arm64 | ARM64 | aarch64)
BUILD_ARCH=arm64
graphic_driver=aarch64_rpi
;;
arm | ARM | aarch | armv7l | armhf)
bashio::log.fatal "Unsupported Machine Architecture: $BUILD_ARCH" 1>&2
exit 1
;;
*)
bashio::log.fatal "Unsupported Machine Architecture: $BUILD_ARCH" 1>&2
exit 1
;;
esac
bashio::log.info "... architecture detected: ${BUILD_ARCH}"
#graphic_driver="$(bashio::config "graphic_driver")"
case "$graphic_driver" in
x64_AMD)
if [[ "$BUILD_ARCH" != amd64 ]]; then bashio::log.fatal "Wrong architecture, $graphic_driver doesn't support $BUILD_ARCH"; fi
[ -f /usr/bin/apt ] && DOCKER_MODS=linuxserver/mods:jellyfin-amd && run_mods >/dev/null && bashio::log.green "... done"
[ -f /usr/bin/apk ] && apk add --no-cache mesa-dri-classic mesa-vdpau-gallium linux-firmware-radeon >/dev/null && bashio::log.green "... done"
;;
x64_NVIDIA)
if [[ "$BUILD_ARCH" != amd64 ]]; then bashio::log.fatal "Wrong architecture, $graphic_driver doesn't support $BUILD_ARCH"; fi
[ -f /usr/bin/apk ] && apk add --no-cache linux-firmware-radeon >/dev/null && bashio::log.green "... done"
[ -f /usr/bin/apt ] && apt-get -yqq install libcuda1 libnvcuvid1 libnvidia-encode1 nvidia-opencl-icd nvidia-vdpau-driver nvidia-driver-libs nvidia-kernel-dkms libva2 vainfo libva-wayland2 >/dev/null && bashio::log.green "... done"
;;
x64_Intel)
if [[ "$BUILD_ARCH" != amd64 ]]; then bashio::log.fatal "Wrong architecture, $graphic_driver doesn't support $BUILD_ARCH"; fi
[ -f /usr/bin/apk ] && apk add --no-cache opencl mesa-dri-gallium mesa-vulkan-intel mesa-dri-intel intel-media-driver >/dev/null && bashio::log.green "... done"
[ -f /usr/bin/apt ] && DOCKER_MODS=linuxserver/mods:jellyfin-opencl-intel && run_mods && apt-get -yqq install intel-opencl-icd intel-media-va-driver-non-free i965-va-driver-shaders mesa-va-drivers libmfx1 libva2 vainfo libva-wayland2 >/dev/null && bashio::log.green "... done"
;;
aarch64_rpi)
if [[ "$BUILD_ARCH" != arm64 ]]; then bashio::log.fatal "Wrong architecture, $graphic_driver doesn't support $BUILD_ARCH"; fi
bashio::log.info "Installing Rpi graphic drivers"
[ -f /usr/bin/apk ] && apk add --no-cache mesa-dri-vc4 mesa-dri-swrast mesa-gbm xf86-video-fbdev >/dev/null && bashio::log.green "... done"
[ -f /usr/bin/apt ] && apt-get -yqq install libgles2-mesa libgles2-mesa-dev xorg-dev >/dev/null && bashio::log.green "... done"
;;
esac
# Main run logic
run_mods() {
echo "[mod-init] Attempting to run Docker Modification Logic"
for DOCKER_MOD in $(echo "${DOCKER_MODS}" | tr '|' '\n'); do
# Support alternative endpoints
if [[ ${DOCKER_MOD} == ghcr.io/* ]] || [[ ${DOCKER_MOD} == linuxserver/* ]]; then
DOCKER_MOD="${DOCKER_MOD#ghcr.io/*}"
ENDPOINT="${DOCKER_MOD%%:*}"
USERNAME="${DOCKER_MOD%%/*}"
REPO="${ENDPOINT#*/}"
TAG="${DOCKER_MOD#*:}"
if [[ ${TAG} == "${DOCKER_MOD}" ]]; then
TAG="latest"
fi
FILENAME="${USERNAME}.${REPO}.${TAG}"
AUTH_URL="https://ghcr.io/token?scope=repository%3A${USERNAME}%2F${REPO}%3Apull"
MANIFEST_URL="https://ghcr.io/v2/${ENDPOINT}/manifests/${TAG}"
BLOB_URL="https://ghcr.io/v2/${ENDPOINT}/blobs/"
MODE="ghcr"
else
ENDPOINT="${DOCKER_MOD%%:*}"
USERNAME="${DOCKER_MOD%%/*}"
REPO="${ENDPOINT#*/}"
TAG="${DOCKER_MOD#*:}"
if [[ ${TAG} == "${DOCKER_MOD}" ]]; then
TAG="latest"
fi
FILENAME="${USERNAME}.${REPO}.${TAG}"
AUTH_URL="https://auth.docker.io/token?service=registry.docker.io&scope=repository:${ENDPOINT}:pull"
MANIFEST_URL="https://registry-1.docker.io/v2/${ENDPOINT}/manifests/${TAG}"
BLOB_URL="https://registry-1.docker.io/v2/${ENDPOINT}/blobs/"
MODE="dockerhub"
fi
# Kill off modification logic if any of the usernames are banned
for BANNED in $(curl -s https://raw.githubusercontent.com/linuxserver/docker-mods/master/blacklist.txt); do
if [[ "${BANNED,,}" == "${USERNAME,,}" ]]; then
if [[ -z ${RUN_BANNED_MODS+x} ]]; then
echo "[mod-init] ${DOCKER_MOD} is banned from use due to reported abuse aborting mod logic"
return
else
echo "[mod-init] You have chosen to run banned mods ${DOCKER_MOD} will be applied"
fi
fi
done
echo "[mod-init] Applying ${DOCKER_MOD} files to container"
# Get Dockerhub token for api operations
TOKEN="$(
curl -f --retry 10 --retry-max-time 60 --retry-connrefused \
--silent \
--header 'GET' \
"${AUTH_URL}" |
jq -r '.token'
)"
# Determine first and only layer of image
SHALAYER=$(get_blob_sha "${MODE}" "${TOKEN}" "${MANIFEST_URL}")
# Check if we have allready applied this layer
if [[ -f "/${FILENAME}" ]] && [[ "${SHALAYER}" == "$(cat /"${FILENAME}")" ]]; then
echo "[mod-init] ${DOCKER_MOD} at ${SHALAYER} has been previously applied skipping"
else
# Download and extract layer to /
curl -f --retry 10 --retry-max-time 60 --retry-connrefused \
--silent \
--location \
--request GET \
--header "Authorization: Bearer ${TOKEN}" \
"${BLOB_URL}${SHALAYER}" -o \
/modtarball.tar.xz
mkdir -p /tmp/mod
tar xzf /modtarball.tar.xz -C /tmp/mod
if [[ -d /tmp/mod/etc/s6-overlay ]]; then
if [[ -d /tmp/mod/etc/cont-init.d ]]; then
rm -rf /tmp/mod/etc/cont-init.d
fi
if [[ -d /tmp/mod/etc/services.d ]]; then
rm -rf /tmp/mod/etc/services.d
fi
fi
shopt -s dotglob
cp -R /tmp/mod/* /
shopt -u dotglob
rm -rf /tmp/mod
rm -rf /modtarball.tar.xz
echo "${SHALAYER}" >"/${FILENAME}"
echo "[mod-init] ${DOCKER_MOD} applied to container"
fi
done
}
fi

10
.templates/99-custom_script.sh Executable file
View File

@@ -0,0 +1,10 @@
#!/usr/bin/with-contenv bashio
# shellcheck shell=bash
set -e
CONFIGSOURCE=$(bashio::config "CONFIG_LOCATION")
CONFIGSOURCE="$(dirname "${CONFIGSOURCE}")"
if [ -f "$CONFIGSOURCE"/script.sh ]; then
"$CONFIGSOURCE"./script.sh
fi

View File

@@ -0,0 +1,10 @@
# All env variables set in this file will be enabled in the app
# This allows enabling more options that normally available in the addon options
# This file must be filled according to the yaml format.
# If the format is invalid, the addon will note an error.
# To validate your yaml, you can use the free online tool http://www.yamllint.com/
# You can use env both for the addon, and for bashio. For bashio, use BASHIO_LOG_LEVEL instead of LOG_LEVEL
# EXAMPLE of the format (you need to remove the # for it to become active)
# TZ: Europe/Paris

28
.templates/ha_autoapps.sh Executable file
View File

@@ -0,0 +1,28 @@
#!/bin/sh
# shellcheck disable=SC2015
set -e
##############################
# Automatic apps download #
##############################
PACKAGES="$1"
echo "To install : $PACKAGES"
# Install bash if needed
if ! command -v bash >/dev/null 2>/dev/null; then
(apt-get update && apt-get install -yqq --no-install-recommends bash || apk add --no-cache bash) >/dev/null
fi
# Install curl if needed
if ! command -v curl >/dev/null 2>/dev/null; then
(apt-get update && apt-get install -yqq --no-install-recommends curl || apk add --no-cache curl) >/dev/null
fi
# Call apps installer script if needed
curl -f -L -s -S "https://raw.githubusercontent.com/Mesteriis/hassio-addons-avm/master/.templates/ha_automatic_packages.sh" --output /ha_automatic_packages.sh
chmod 777 /ha_automatic_packages.sh
eval /./ha_automatic_packages.sh "${PACKAGES:-}"
# Clean
rm /ha_automatic_packages.sh

View File

@@ -0,0 +1,275 @@
#!/bin/bash
set -e
########
# INIT #
########
#Verbose or not
VERBOSE=false
#Avoid fails on non declared variables
set +u 2>/dev/null || true
#If no packages, empty
PACKAGES="${*:-}"
#Avoids messages if non interactive
(echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections) &>/dev/null || true
[ "$VERBOSE" = true ] && echo "ENV : $PACKAGES"
############################
# CHECK WHICH BASE IS USED #
############################
if command -v "apk" &>/dev/null; then
# If apk based
[ "$VERBOSE" = true ] && echo "apk based"
PACKMANAGER="apk"
elif command -v "apt" &>/dev/null; then
# If apt-get based
[ "$VERBOSE" = true ] && echo "apt based"
PACKMANAGER="apt"
elif command -v "pacman" &>/dev/null; then
# If apt-get based
[ "$VERBOSE" = true ] && echo "pacman based"
PACKMANAGER="pacman"
fi
###################
# DEFINE PACKAGES #
###################
# ADD GENERAL ELEMENTS
######################
PACKAGES="$PACKAGES jq curl vim ca-certificates"
# FOR EACH SCRIPT, SELECT PACKAGES
##################################
# Scripts
for files in "/etc/cont-init.d" "/etc/services.d"; do
# Next directory if does not exists
if ! ls $files 1>/dev/null 2>&1; then continue; fi
# Test each possible command
COMMAND="nginx"
if grep -q -rnw "$files/" -e "$COMMAND" && ! command -v $COMMAND &>/dev/null; then
[ "$VERBOSE" = true ] && echo "$COMMAND required"
[ "$PACKMANAGER" = "apk" ] && PACKAGES="$PACKAGES nginx"
[ "$PACKMANAGER" = "apt" ] && PACKAGES="$PACKAGES nginx"
[ "$PACKMANAGER" = "pacman" ] && PACKAGES="$PACKAGES nginx"
if ls /etc/nginx 1>/dev/null 2>&1; then mv /etc/nginx /etc/nginx2; fi
fi
COMMAND="mount"
if grep -q -rnw "$files/" -e "$COMMAND"; then
[ "$VERBOSE" = true ] && echo "$COMMAND required"
[ "$PACKMANAGER" = "apk" ] && PACKAGES="$PACKAGES exfatprogs ntfs-3g squashfs-tools fuse lsblk"
[ "$PACKMANAGER" = "apt" ] && PACKAGES="$PACKAGES exfat* ntfs* squashfs-tools util-linux"
#[ "$PACKMANAGER" = "pacman" ] && PACKAGES="$PACKAGES ntfs-3g"
fi
COMMAND="ping"
if grep -q -rnw "$files/" -e "$COMMAND" && ! command -v $COMMAND &>/dev/null; then
[ "$VERBOSE" = true ] && echo "$COMMAND required"
[ "$PACKMANAGER" = "apk" ] && PACKAGES="$PACKAGES iputils"
[ "$PACKMANAGER" = "apt" ] && PACKAGES="$PACKAGES iputils-ping"
#[ "$PACKMANAGER" = "pacman" ] && PACKAGES="$PACKAGES iputils"
fi
COMMAND="nmap"
if grep -q -rnw "$files/" -e "$COMMAND"; then
[ "$VERBOSE" = true ] && echo "$COMMAND required"
[ "$PACKMANAGER" = "apk" ] && PACKAGES="$PACKAGES nmap nmap-scripts"
[ "$PACKMANAGER" = "apt" ] && PACKAGES="$PACKAGES nmap"
#[ "$PACKMANAGER" = "pacman" ] && PACKAGES="$PACKAGES iputils"
fi
COMMAND="cifs"
if grep -q -rnw "$files/" -e "$COMMAND"; then
[ "$VERBOSE" = true ] && echo "$COMMAND required"
[ "$PACKMANAGER" = "apk" ] && PACKAGES="$PACKAGES cifs-utils keyutils"
[ "$PACKMANAGER" = "apt" ] && PACKAGES="$PACKAGES cifs-utils keyutils"
[ "$PACKMANAGER" = "pacman" ] && PACKAGES="$PACKAGES cifs-utils keyutils"
fi
COMMAND="smbclient"
if grep -q -rnw "$files/" -e "$COMMAND" && ! command -v $COMMAND &>/dev/null; then
[ "$VERBOSE" = true ] && echo "$COMMAND required"
[ "$PACKMANAGER" = "apk" ] && PACKAGES="$PACKAGES samba samba-client ntfs-3g"
[ "$PACKMANAGER" = "apt" ] && PACKAGES="$PACKAGES samba smbclient ntfs-3g"
[ "$PACKMANAGER" = "pacman" ] && PACKAGES="$PACKAGES samba smbclient"
fi
COMMAND="dos2unix"
if grep -q -rnw "$files/" -e "$COMMAND" && ! command -v $COMMAND &>/dev/null; then
[ "$VERBOSE" = true ] && echo "$COMMAND required"
[ "$PACKMANAGER" = "apk" ] && PACKAGES="$PACKAGES dos2unix"
[ "$PACKMANAGER" = "apt" ] && PACKAGES="$PACKAGES dos2unix"
[ "$PACKMANAGER" = "pacman" ] && PACKAGES="$PACKAGES dos2unix"
fi
COMMAND="openvpn"
if grep -q -rnw "$files/" -e "$COMMAND" && ! command -v $COMMAND &>/dev/null; then
[ "$VERBOSE" = true ] && echo "$COMMAND required"
[ "$PACKMANAGER" = "apk" ] && PACKAGES="$PACKAGES coreutils openvpn"
[ "$PACKMANAGER" = "apt" ] && PACKAGES="$PACKAGES coreutils openvpn"
[ "$PACKMANAGER" = "pacman" ] && PACKAGES="$PACKAGES coreutils openvpn"
fi
COMMAND="jq"
if grep -q -rnw "$files/" -e "$COMMAND" && ! command -v $COMMAND &>/dev/null; then
[ "$VERBOSE" = true ] && echo "$COMMAND required"
[ "$PACKMANAGER" = "apk" ] && PACKAGES="$PACKAGES jq"
[ "$PACKMANAGER" = "apt" ] && PACKAGES="$PACKAGES jq"
[ "$PACKMANAGER" = "pacman" ] && PACKAGES="$PACKAGES jq"
fi
COMMAND="yamllint"
if grep -q -rnw "$files/" -e "$COMMAND" && ! command -v $COMMAND &>/dev/null; then
[ "$VERBOSE" = true ] && echo "$COMMAND required"
[ "$PACKMANAGER" = "apk" ] && PACKAGES="$PACKAGES yamllint"
[ "$PACKMANAGER" = "apt" ] && PACKAGES="$PACKAGES yamllint"
[ "$PACKMANAGER" = "pacman" ] && PACKAGES="$PACKAGES yamllint"
fi
COMMAND="git"
if grep -q -rnw "$files/" -e "$COMMAND" && ! command -v $COMMAND &>/dev/null; then
[ "$VERBOSE" = true ] && echo "$COMMAND required"
[ "$PACKMANAGER" = "apk" ] && PACKAGES="$PACKAGES git"
[ "$PACKMANAGER" = "apt" ] && PACKAGES="$PACKAGES git"
[ "$PACKMANAGER" = "pacman" ] && PACKAGES="$PACKAGES git"
fi
COMMAND="sponge"
if grep -q -rnw "$files/" -e "$COMMAND" && ! command -v $COMMAND &>/dev/null; then
[ "$VERBOSE" = true ] && echo "$COMMAND required"
[ "$PACKMANAGER" = "apk" ] && PACKAGES="$PACKAGES moreutils"
[ "$PACKMANAGER" = "apt" ] && PACKAGES="$PACKAGES moreutils"
[ "$PACKMANAGER" = "pacman " ] && PACKAGES="$PACKAGES moreutils"
fi
COMMAND="sqlite3"
if grep -q -rnw "$files/" -e "$COMMAND" && ! command -v $COMMAND &>/dev/null; then
[ "$VERBOSE" = true ] && echo "$COMMAND required"
[ "$PACKMANAGER" = "apk" ] && PACKAGES="$PACKAGES sqlite"
[ "$PACKMANAGER" = "apt" ] && PACKAGES="$PACKAGES sqlite3"
[ "$PACKMANAGER" = "pacman" ] && PACKAGES="$PACKAGES sqlite3"
fi
COMMAND="pip"
if grep -q -rnw "$files/" -e "$COMMAND" && ! command -v $COMMAND &>/dev/null; then
[ "$VERBOSE" = true ] && echo "$COMMAND required"
[ "$PACKMANAGER" = "apk" ] && PACKAGES="$PACKAGES py3-pip"
[ "$PACKMANAGER" = "apt" ] && PACKAGES="$PACKAGES pip"
[ "$PACKMANAGER" = "pacman" ] && PACKAGES="$PACKAGES pip"
fi
COMMAND="wget"
if grep -q -rnw "$files/" -e "$COMMAND" && ! command -v $COMMAND &>/dev/null; then
[ "$VERBOSE" = true ] && echo "$COMMAND required"
[ "$PACKMANAGER" = "apk" ] && PACKAGES="$PACKAGES wget"
[ "$PACKMANAGER" = "apt" ] && PACKAGES="$PACKAGES wget"
[ "$PACKMANAGER" = "wget" ] && PACKAGES="$PACKAGES wget"
fi
done
####################
# INSTALL ELEMENTS #
####################
# Install apps
[ "$VERBOSE" = true ] && echo "installing packages $PACKAGES"
if [ "$PACKMANAGER" = "apt" ]; then apt-get update >/dev/null; fi
if [ "$PACKMANAGER" = "pacman" ]; then pacman -Sy >/dev/null; fi
# Install apps one by one to allow failures
# shellcheck disable=SC2086
for packagestoinstall in $PACKAGES; do
[ "$VERBOSE" = true ] && echo "... $packagestoinstall"
if [ "$PACKMANAGER" = "apk" ]; then
apk add --no-cache "$packagestoinstall" &>/dev/null || (echo "Error : $packagestoinstall not found" && touch /ERROR)
elif [ "$PACKMANAGER" = "apt" ]; then
apt-get install -yqq --no-install-recommends "$packagestoinstall" &>/dev/null || (echo "Error : $packagestoinstall not found" && touch /ERROR)
elif [ "$PACKMANAGER" = "pacman" ]; then
pacman --noconfirm -S "$packagestoinstall" &>/dev/null || (echo "Error : $packagestoinstall not found" && touch /ERROR)
fi
[ "$VERBOSE" = true ] && echo "... $packagestoinstall done"
done
# Clean after install
[ "$VERBOSE" = true ] && echo "Cleaning apt cache"
if [ "$PACKMANAGER" = "apt" ]; then apt-get clean >/dev/null; fi
# Replace nginx if installed
if ls /etc/nginx2 1>/dev/null 2>&1; then
[ "$VERBOSE" = true ] && echo "replace nginx2"
rm -r /etc/nginx
mv /etc/nginx2 /etc/nginx
mkdir -p /var/log/nginx
touch /var/log/nginx/error.log
fi
#######################
# INSTALL MANUAL APPS #
#######################
# Install micro texteditor
curl https://getmic.ro | bash
mv micro /usr/bin
micro -plugin install bounce
micro -plugin install filemanager
for files in "/etc/services.d" "/etc/cont-init.d"; do
# Next directory if does not exists
if ! ls $files 1>/dev/null 2>&1; then continue; fi
# Bashio
if grep -q -rnw "$files/" -e 'bashio' && [ ! -f "/usr/bin/bashio" ]; then
[ "$VERBOSE" = true ] && echo "install bashio"
BASHIO_VERSION="0.14.3"
mkdir -p /tmp/bashio
curl -f -L -s -S "https://github.com/hassio-addons/bashio/archive/v${BASHIO_VERSION}.tar.gz" | tar -xzf - --strip 1 -C /tmp/bashio
mv /tmp/bashio/lib /usr/lib/bashio
ln -s /usr/lib/bashio/bashio /usr/bin/bashio
rm -rf /tmp/bashio
fi
# Lastversion
COMMAND="lastversion"
if grep -q -rnw "$files/" -e "$COMMAND" && ! command -v $COMMAND &>/dev/null; then
[ "$VERBOSE" = true ] && echo "install $COMMAND"
pip install $COMMAND
fi
# Tempio
if grep -q -rnw "$files/" -e 'tempio' && [ ! -f "/usr/bin/tempio" ]; then
[ "$VERBOSE" = true ] && echo "install tempio"
TEMPIO_VERSION="2021.09.0"
BUILD_ARCH="$(bashio::info.arch)"
curl -f -L -f -s -o /usr/bin/tempio "https://github.com/home-assistant/tempio/releases/download/${TEMPIO_VERSION}/tempio_${BUILD_ARCH}"
chmod a+x /usr/bin/tempio
fi
# Mustache
COMMAND="mustache"
if grep -q -rnw "$files/" -e "$COMMAND" && ! command -v $COMMAND &>/dev/null; then
[ "$VERBOSE" = true ] && echo "$COMMAND required"
[ "$PACKMANAGER" = "apk" ] && apk add --no-cache go npm &&
apk upgrade --no-cache &&
apk add --no-cache --virtual .build-deps build-base git go &&
go get -u github.com/quantumew/mustache-cli &&
cp "$GOPATH"/bin/* /usr/bin/ &&
rm -rf "$GOPATH" /var/cache/apk/* /tmp/src &&
apk del .build-deps xz build-base
[ "$PACKMANAGER" = "apt" ] && apt-get update &&
apt-get install -yqq go npm node-mustache
fi
done
if [ -f /ERROR ]; then
exit 1
fi

36
.templates/ha_automodules.sh Executable file
View File

@@ -0,0 +1,36 @@
#!/bin/sh
# shellcheck disable=SC2015
set -e
##############################
# Automatic modules download #
##############################
MODULES="$1"
MODULES="$MODULES 00-banner.sh 01-custom_script.sh 01-config_yaml.sh 00-global_var.sh"
echo "To download : $MODULES"
# Install bash if not available
if ! command -v bash >/dev/null 2>/dev/null; then
(apt-get update && apt-get install -yqq --no-install-recommends bash || apk add --no-cache bash) >/dev/null
fi
# Install curl if not available
if ! command -v curl >/dev/null 2>/dev/null; then
(apt-get update && apt-get install -yqq --no-install-recommends curl || apk add --no-cache curl) >/dev/null
fi
# Install ca-certificates if not available
apt-get update && apt-get install -yqq --no-install-recommends ca-certificates || apk add --no-cache ca-certificates >/dev/null || true
# Create folder for scripts
mkdir -p /etc/cont-init.d
# Download scripts
for scripts in $MODULES; do
echo "$scripts" && curl -f -L -s -S "https://raw.githubusercontent.com/Mesteriis/hassio-addons-avm/master/.templates/$scripts" -o /etc/cont-init.d/"$scripts" &&
[ "$(sed -n '/\/bin/p;q' /etc/cont-init.d/"$scripts")" != "" ] ||
(echo "script failed to install $scripts" && exit 1)
done
chmod -R 755 /etc/cont-init.d

59
.templates/ha_entrypoint.sh Executable file
View File

@@ -0,0 +1,59 @@
#!/command/with-contenv bashio
# shellcheck shell=bash
echo "Starting..."
####################
# Starting scripts #
####################
for SCRIPTS in /etc/cont-init.d/*; do
[ -e "$SCRIPTS" ] || continue
echo "$SCRIPTS: executing"
# Check if run as root
if test "$(id -u)" == 0 && test "$(id -u)" == 0; then
chown "$(id -u)":"$(id -g)" "$SCRIPTS"
chmod a+x "$SCRIPTS"
else
bashio::log.warning "Script executed with user $(id -u):$(id -g), things can break and chown won't work"
# Disable chown and chmod in scripts
sed -i "s/^chown /true # chown /g" "$SCRIPTS"
sed -i "s/ chown / true # chown /g" "$SCRIPTS"
sed -i "s/^chmod /true # chmod /g" "$SCRIPTS"
sed -i "s/ chmod / true # chmod /g" "$SCRIPTS"
fi
# Get current shebang, if not available use another
currentshebang="$(sed -n '1{s/^#![[:blank:]]*//p;q}' "$SCRIPTS")"
if [ ! -f "${currentshebang%% *}" ]; then
for shebang in "/command/with-contenv bashio" "/usr/bin/env bashio" "/usr/bin/bashio" "/bin/bash" "/bin/sh"; do if [ -f "${shebang%% *}" ]; then break; fi; done
sed -i "s|$currentshebang|$shebang|g" "$SCRIPTS"
fi
# Use source to share env variables when requested
if [ "${ha_entry_source:-null}" = true ] && command -v "source" &>/dev/null; then
# Exit cannot be used with source
sed -i "s/(.*\s|^)exit ([0-9]+)/\1 return \2 || exit \2/g" "$SCRIPTS"
sed -i "s/bashio::exit.nok/return 1/g" "$SCRIPTS"
sed -i "s/bashio::exit.ok/return 0/g" "$SCRIPTS"
# shellcheck source=/dev/null
source "$SCRIPTS" || echo -e "\033[0;31mError\033[0m : $SCRIPTS exiting $?"
else
# Support for posix only shell
/."$SCRIPTS" || echo -e "\033[0;31mError\033[0m : $SCRIPTS exiting $?"
fi
# Cleanup
rm "$SCRIPTS"
done
######################
# Starting container #
######################
echo " "
echo -e "\033[0;32mStarting the upstream container\033[0m"
echo " "
# Launch lsio mods
if [ -f /docker-mods ]; then exec /docker-mods; fi

View File

@@ -0,0 +1,60 @@
#!/bin/sh
set -e
##########################################
# Global modifications before entrypoint #
##########################################
# Corrects permissions for s6 v3
################################
PUID="${PUID:-0}"
PGID="${PGID:-0}"
if [ -f /ha_entrypoint.sh ]; then
chown -R "$PUID:$PGID" /ha_entrypoint.sh
chmod -R 755 /ha_entrypoint.sh
fi
if [ -d /etc/cont-init.d ]; then
chown -R "$PUID:$PGID" /etc/cont-init.d
chmod -R 755 /etc/cont-init.d
fi
if [ -d /etc/services.d ]; then
chown -R "$PUID:$PGID" /etc/services.d
chmod -R 755 /etc/services.d
fi
if [ -d /etc/s6-rc.d ]; then
chown -R "$PUID:$PGID" /etc/s6-rc.d
chmod -R 755 /etc/s6-rc.d
fi
# Correct shebang in entrypoint
###############################
# Make s6 contenv if needed
mkdir -p /run/s6/container_environment
# Check if shebang exists
for shebang in "/command/with-contenv bashio" "/usr/bin/with-contenv bashio" "/usr/bin/env bashio" "/usr/bin/bashio" "/usr/bin/bash" "/usr/bin/sh" "/bin/bash" "/bin/sh"; do
if [ -f "${shebang%% *}" ]; then
break
fi
done
# Define shebang
sed -i "s|/command/with-contenv bashio|$shebang|g" /ha_entrypoint.sh
# Correct for scripts
for string in "/command/with-contenv bashio" "/usr/bin/with-contenv bashio"; do
for files in $(grep -sril "$string" /etc/cont-init.d /etc/services.d /etc/s6-overlay/s6-rc.d); do
sed -i "s|$string|$shebang|g" "$files"
done
done
# Avoid interference with LOG_LEVEL used in the app
if [ -f /usr/lib/bashio/bashio.sh ]; then
sed -i 's|{LOG_LEVEL:|{BASHIO_LOG_LEVEL:|g' /usr/lib/bashio/bashio.sh
fi

59
.templates/ha_lsio.sh Executable file
View File

@@ -0,0 +1,59 @@
#!/bin/sh
# shellcheck disable=SC2013,SC2016,SC2236
set -e
#############################
# Modify global lsio images #
#############################
# Set variable
CONFIGLOCATION="${1:-/config}"
echo "Setting config to $CONFIGLOCATION"
# Avoid custom-init.d duplications
for file in $(grep -sril 'Potential tampering with custom' /etc/cont-init.d /etc/services.d /etc/s6-overlay/s6-rc.d); do
rm -f "$file"
done
# If custom config
if [ "$CONFIGLOCATION" != "/config" ]; then
# Create new config folder if needed
for file in $(grep -srl "PUID" /etc/cont-init.d /etc/s6-overlay/s6-rc.d); do
sed -i "1a mkdir -p $CONFIGLOCATION" "$file"
done
# Correct config location
for file in $(grep -Esril "/config[ '\"/]|/config\$" /etc /defaults); do
sed -Ei "s=(/config)+(/| |$|\"|\')=$CONFIGLOCATION\2=g" "$file"
done
fi
# Allow UID and GID setting
for file in $(grep -srl "PUID" /etc/cont-init.d /etc/s6-overlay/s6-rc.d); do
sed -i 's/bash/bashio/g' "$file" && sed -i '1a PUID="$(if bashio::config.has_value "PUID"; then bashio::config "PUID"; else echo "0"; fi)"' "$file"
sed -i '1a PGID="$(if bashio::config.has_value "PGID"; then bashio::config "PGID"; else echo "0"; fi)"' "$file"
done
# Avoid chmod /config if ha config mounted
if [ -f /config/configuration.yaml ] || [ -f /config/configuration.json ]; then
for file in /etc/services.d/*/* /etc/cont-init.d/* /etc/s6-overlay/s6-rc.d/*/*; do
if [ -f "$file" ] && [ ! -z "$(awk '/chown.*abc:abc.*\\/,/.*\/config( |$)/{print FILENAME}' "$file")" ]; then
sed -i "s|/config$|/data|g" "$file"
fi
done
fi
# Send crond logs to addon logs
if [ -f /etc/s6-overlay/s6-rc.d/svc-cron/run ]; then
sed -i "/exec busybox crond/c exec busybox crond -f -S -L /proc/1/fd/1" /etc/s6-overlay/s6-rc.d/svc-cron/run
sed -i "/exec \/usr\/sbin\/cron/c exec /usr/sbin/cron -f &>/proc/1/fd/1" /etc/s6-overlay/s6-rc.d/svc-cron/run
fi
# Replace lsiown if not found
if [ ! -f /usr/bin/lsiown ]; then
for file in $(grep -sril "lsiown" /etc); do
sed -i "s|lsiown|chown|g" "$file"
done
fi

View File

@@ -0,0 +1,9 @@
#!/usr/bin/with-contenv bashio
# shellcheck shell=bash
#################
# CODE INJECTOR #
#################
# Any commands written in this bash script will be executed at addon start
# See guide here : https://github.com/Mesteriis/hassio-addons-avm/wiki/Add%E2%80%90ons-feature-:-customisation

View File

@@ -0,0 +1,9 @@
#Define colors
red=1
green=2
yellow=3
blue=4
violet=5
teal=6
echo "$(tput setaf $red)ENV exported : $word$(tput sgr0)"
echo -e "\033[0;31mError\033[0m : Text"

View File

@@ -1,66 +0,0 @@
---
ignore: |
*/translations/*.yaml
rules:
braces:
level: error
min-spaces-inside: 0
max-spaces-inside: 1
min-spaces-inside-empty: -1
max-spaces-inside-empty: -1
brackets:
level: error
min-spaces-inside: 0
max-spaces-inside: 0
min-spaces-inside-empty: -1
max-spaces-inside-empty: -1
colons:
level: error
max-spaces-before: 0
max-spaces-after: 1
commas:
level: error
max-spaces-before: 0
min-spaces-after: 1
max-spaces-after: 1
comments:
level: error
require-starting-space: true
min-spaces-from-content: 2
comments-indentation:
level: error
document-end:
level: error
present: false
document-start:
level: error
present: true
empty-lines:
level: error
max: 1
max-start: 0
max-end: 1
hyphens:
level: error
max-spaces-after: 1
indentation:
level: error
spaces: 2
indent-sequences: true
check-multi-line-strings: false
key-duplicates:
level: error
line-length:
level: warning
max: 120
allow-non-breakable-words: true
allow-non-breakable-inline-mappings: true
new-line-at-end-of-file:
level: error
new-lines:
level: error
type: unix
trailing-spaces:
level: error
truthy:
level: error

View File

@@ -1,6 +1,6 @@
# MIT License
Copyright (c) 2017-2021 Franck Nijhof <frenck@addons.community>
Copyright (c) 2017-2021 Alexander Mescheryakov <avm@sh-inc.ru>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -1,15 +0,0 @@
## Whats changed
## ⬆️ Dependency updates
- ⬆️ Bump brpaz/hadolint-action from v1.4.0 to v1.5.0 @dependabot (#74)
- ⬆️ Bump frenck/action-addon-linter from 2 to 2.1 @dependabot (#75)
- ⬆️ Bump actions/stale from 3.0.18 to 3.0.19 @dependabot (#76)
- ⬆️ Bump frenck/action-addon-information from 1.0.0 to 1.1 @dependabot (#77)
- ⬆️ Bump micnncim/action-label-syncer from 1.2.0 to 1.3.0 @dependabot (#78)
- ⬆️ Bump docker/build-push-action from 2.4.0 to 2.5.0 @dependabot (#79)
- ⬆️ Bump docker/setup-qemu-action from 1.1.0 to 1.2.0 @dependabot (#80)
- ⬆️ Bump actions/cache from 2.1.5 to 2.1.6 @dependabot (#81)
- ⬆️ Bump frenck/action-addon-information from 1.1 to 1.2 @dependabot (#82)
- ⬆️ Upgrades add-on base image to v4.2.1 @frenck (#84)
- ⬆️ Upgrades AirConnect to 0.2.50.5 @frenck (#85)

View File

@@ -1,231 +0,0 @@
# Home Assistant Community Add-on: AirCast
Apple devices use AirPlay to send audio to other devices, but this is not
compatible with Google's Chromecast. This add-on tries to solve this
compatibility gap.
It detects Chromecast players in your network and creates virtual AirPlay
devices for each of them. It acts as a bridge between the AirPlay client
and the real Chromecast player.
## Installation
The installation of this add-on is pretty straightforward and not different in
comparison to installing any other Home Assistant add-on.
1. Search for the “AirCast” add-on in the Supervisor add-on store
and install it.
1. Install the "AirCast" add-on.
1. Start the "AirCast" add-on
1. Check the logs of the "AirCast" add-on to see if everything went well.
After ~30 seconds you should see some log messages appear in the add-on log.
Using your iOS/Mac/iTunes/Airfoil/other clients, you should now see new AirPlay
devices and can try to play audio to them.
## Configuration
**Note**: _Remember to restart the add-on when the configuration is changed._
Example add-on configuration:
```yaml
log_level: info
address: 192.168.1.234
latency_rtp: 5000
latency_http: 0
drift: 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.
These log level also affects the log levels of AirCast server.
### Option: `address`
This option allows you to specify the IP address the AirCast server needs to
bind to. It will automatically detect the interface to use when this option is
left empty. Nevertheless, it might get detected wrong (e.g., in case you have
multiple network interfaces).
### Option: `latency_rtp`
Allows you to tweak the buffering, which is needed when the audio is stuttering
(e.g., low-quality network). This option specifies the number of ms the addon
has to buffer the RTP audio (AirPlay). Setting this value below 500ms is not
recommended! Setting the value to `0` causes the addon the get the value from
AirPlay.
### Option: `latency_http`
Allows you to tweak the buffering, which is needed when the audio is stuttering
(e.g., low-quality network). This option specifies the number of ms the addon
has to buffer the HTTP audio.
**Note**: This option usually is not needed and can be left to `0` in most
cases.
### Option: `drift`
Set to `true` to let timing reference drift (no click).
## Latency options explained
These bridges receive real-time "synchronous" audio from the AirPlay controller
in the format of RTP frames and forward it to the Chromecast player in an HTTP
"asynchronous" continuous audio binary format. In other words,
the AirPlay clients "push" the audio using RTP and the Chromecast players
"pull" the audio using an HTTP GET request.
A player using HTTP to get its audio expects to receive an initial large
portion of audio as the response to its GET and this creates a large enough
buffer to handle most further network congestion/delays. The rest of the audio
transmission is regulated by the player using TCP flow control. However, when
the source is an AirPlay RTP device, there is no such significant portion of
audio available in advance to be sent to the Player, as the audio comes to the
bridge in real time. Every 8ms, an RTP frame is received and is immediately
forwarded as the continuation of the HTTP body. If the Chromecast players
start to play immediately the first received audio sample, expecting an initial
burst to follow, then any network congestion delaying RTP audio will starve
the player and create shuttering.
The `latency_http` option allows a certain amount of silence frames to be sent
to the Chromecast player, in a burst at the beginning. Then, while this
"artificial" silence is being played, it is possible for the bridge to build
a buffer of RTP frames that will then hide network delays that might happen
in further RTP frames transmission. This delays the start of the playback
by `latency_http` ms.
However, RTP frames are transmitted using UDP, which means there is no guarantee
of delivery, so frames might be lost from time to time
(often happens on WiFi networks). To allow detection of lost frames, they are
numbered sequentially (1,2 ... n) so every time two received frames are not
consecutive, the missing ones can be asked again by the AirPlay receiver.
Typically, the bridge forwards immediately every RTP frame using HTTP and again,
in HTTP, the notion of frame numbers does not exist, it is just the continuous
binary audio. So it is not possible to send audio non-sequentially when using
HTTP.
For example, if received RTP frames are numbered 1,2,3,6, this bridge will
forward (once decoded and transformed into raw audio) 1,2,3 immediately using
HTTP but when it receives 6, it will re-ask for 4 and 5 to be resent and
hold 6 while waiting (if 6 was transmitted immediately, the Chromecast
will play 1,2,3,6 ... not nice).
The `latency_rtp` option sets for how long frame 6 shall be held before adding
two silence frames for 4 and 5 and send sending 4,5,6. Obviously, if this delay
is larger than the buffer in the Chromecast player, playback will stop by
lack of audio. Note that `latency_rtp` does not delay playback start.
> **Note**: `latency_rtp` and `latency_http` could have been merged into a
> single `latency` parameter which would have set the max RTP frames holding time
> as well as the duration of the initial additional silence (delay),
> however, all Chromecast devices do properly their own buffering of HTTP audio
> (i.e., they wait until they have received a certain amount of audio before
> starting to play), then adding silence would have introduced an extra
> unnecessary delay in playback.
## Tweaking Aircast
Aircast creates a configuration file called `aircast.xml` in your Home
Assistant configuration directory. This file allows you to tweak each device
separately. Every time it finds a new device, it will be added to that file.
> **NOTE**: It is HIGHLY recommended to stop the addon before making changes
> to the configuration file manually.
## Known issues and limitations
- This add-on does support ARM-based devices, nevertheless, they must
at least be an ARMv7 device. (Raspberry Pi 1 and Zero is not supported).
- The configuration file of AirConnect (used by this add-on) is not
exposed to the user. We plan on adding that feature in a future release.
## Changelog & Releases
This repository keeps a change log using [GitHub's releases][releases]
functionality.
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 Add-ons Discord chat server][discord] for add-on
support and feature requests.
- The [Home Assistant Discord chat server][discord-ha] for general Home
Assistant discussions and questions.
- The Home Assistant [Community Forum][forum].
- Join the [Reddit subreddit][reddit] in [/r/homeassistant][reddit]
You could also [open an issue here][issue] GitHub.
## 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].
## License
MIT License
Copyright (c) 2017-2021 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.
[contributors]: https://github.com/hassio-addons/addon-aircast/graphs/contributors
[discord-ha]: https://discord.gg/c5DvZ4e
[discord]: https://discord.me/hassioaddons
[docs]: https://github.com/hassio-addons/addon-aircast/blob/main/aircast/DOCS.md
[forum]: https://community.home-assistant.io/t/home-assistant-community-add-on-aircast/36742?u=frenck
[frenck]: https://github.com/frenck
[issue]: https://github.com/hassio-addons/addon-aircast/issues
[reddit]: https://reddit.com/r/homeassistant
[releases]: https://github.com/hassio-addons/addon-aircast/releases
[semver]: http://semver.org/spec/v2.0.0.htm

View File

@@ -1,34 +0,0 @@
# Home Assistant Community Add-on: AirCast
[![Release][release-shield]][release] ![Project Stage][project-stage-shield] ![Project Maintenance][maintenance-shield]
[![Discord][discord-shield]][discord] [![Community Forum][forum-shield]][forum]
[![Sponsor Frenck via GitHub Sponsors][github-sponsors-shield]][github-sponsors]
[![Support Frenck on Patreon][patreon-shield]][patreon]
AirPlay capabilities for your Chromecast players.
## About
Apple devices use AirPlay to send audio to other devices, but this is not
compatible with Google's Chromecast. This add-on tries to solve this
compatibility gap.
It detects Chromecast players in your network and creates virtual AirPlay
devices for each of them. It acts as a bridge between the AirPlay client
and the real Chromecast player.
[discord-shield]: https://img.shields.io/discord/478094546522079232.svg
[discord]: https://discord.me/hassioaddons
[forum-shield]: https://img.shields.io/badge/community-forum-brightgreen.svg
[forum]: https://community.home-assistant.io/t/home-assistant-community-add-on-aircast/36742?u=frenck
[github-sponsors-shield]: https://frenck.dev/wp-content/uploads/2019/12/github_sponsor.png
[github-sponsors]: https://github.com/sponsors/frenck
[maintenance-shield]: https://img.shields.io/maintenance/yes/2021.svg
[patreon-shield]: https://frenck.dev/wp-content/uploads/2019/12/patreon.png
[patreon]: https://www.patreon.com/frenck
[project-stage-shield]: https://img.shields.io/badge/project%20stage-production%20ready-brightgreen.svg
[release-shield]: https://img.shields.io/badge/version-v3.1.1-blue.svg
[release]: https://github.com/hassio-addons/addon-aircast/tree/v3.1.1

View File

@@ -1,33 +0,0 @@
{
"name": "AirCast",
"version": "3.1.1",
"slug": "aircast",
"description": "AirPlay capabilities for your Chromecast devices.",
"url": "https://github.com/hassio-addons/addon-aircast",
"startup": "services",
"init": false,
"arch": [
"aarch64",
"amd64",
"armv7",
"i386"
],
"hassio_api": true,
"host_network": true,
"map": [
"config:rw"
],
"options": {
"latency_rtp": 0,
"latency_http": 0,
"drift": false
},
"schema": {
"log_level": "list(trace|debug|info|notice|warning|error|fatal)?",
"address": "str?",
"latency_rtp": "int",
"latency_http": "int",
"drift": "bool"
},
"image": "ghcr.io/hassio-addons/aircast/{arch}"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

View File

@@ -1,29 +0,0 @@
---
configuration:
log_level:
name: Log level
description: >-
Controls the level of log details the add-on provides.
address:
name: Address
description: >-
Allows you to specify the IP address the AirCast server needs to
bind to.
latency_rtp:
name: RTP Latency
description: >-
Allows you to tweak the buffering, which is needed when the audio is
stuttering (e.g., low-quality network). This option specifies the number
of ms the add-on has to buffer the RTP audio (AirPlay). Setting this value
below 500ms is not recommended! Setting the value to 0 makes the add-on
to get the value from AirPlay.
latency_http:
name: HTTP Latency
description: >-
Allows you to tweak the buffering, which is needed when the audio is
stuttering (e.g., low-quality network). This option specifies the number
of ms the add-on has to buffer the HTTP audio.
drift:
name: Drift
description: >-
Allow to let timing reference drift (no click).

View File

@@ -1,15 +0,0 @@
## Whats changed
## ⬆️ Dependency updates
- ⬆️ Bump brpaz/hadolint-action from v1.4.0 to v1.5.0 @dependabot (#58)
- ⬆️ Bump frenck/action-addon-linter from 2 to 2.1 @dependabot (#59)
- ⬆️ Bump actions/stale from 3.0.18 to 3.0.19 @dependabot (#60)
- ⬆️ Bump frenck/action-addon-information from 1.0.0 to 1.1 @dependabot (#61)
- ⬆️ Bump micnncim/action-label-syncer from 1.2.0 to 1.3.0 @dependabot (#62)
- ⬆️ Bump docker/build-push-action from 2.4.0 to 2.5.0 @dependabot (#63)
- ⬆️ Bump actions/cache from 2.1.5 to 2.1.6 @dependabot (#65)
- ⬆️ Bump docker/setup-qemu-action from 1.1.0 to 1.2.0 @dependabot (#64)
- ⬆️ Bump frenck/action-addon-information from 1.1 to 1.2 @dependabot (#66)
- ⬆️ Upgrades add-on base image to v4.2.1 @frenck (#70)
- ⬆️ Upgrades AirConnect to 0.2.50.5 @frenck (#71)

View File

@@ -1,245 +0,0 @@
# Home Assistant Community Add-on: AirSonos
Apple devices use AirPlay to send audio to other devices, but this is not
compatible with Sonos players. This add-on tries to solve this
compatibility gap.
It detects Sonos players in your network and creates virtual AirPlay
devices for each of them. It acts as a bridge between the AirPlay client
and the real Sonos device.
Since Sonos uses UPnP, the add-on might also work for other UPnP players
(e.g., newer Samsung televisions).
## Installation
The installation of this add-on is pretty straightforward and not different in
comparison to installing any other Home Assistant add-on.
1. Search for the “AirSonos” add-on in the Supervisor add-on store
and install it.
1. Start the "AirSonos" add-on
1. Check the logs of the "AirSonos" add-on to see if everything went well.
After ~30 seconds you should see some log messages appear in the add-on log.
Using your iOS/Mac/iTunes/Airfoil/other clients, you should now see new AirPlay
devices and can try to play audio to them.
## Configuration
**Note**: _Remember to restart the add-on when the configuration is changed._
Example add-on configuration:
```yaml
log_level: info
address: 192.168.1.234
port: 49152
latency_rtp: 1000
latency_http: 2000
drift: 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.
These log level also affects the log levels of AirSonos server.
### Option: `address`
This option allows you to specify the IP address the AirSonos server needs to
bind to. It will automatically detect the interface to use when this option is
left empty. Nevertheless, it might get detected wrong (e.g., in case you have
multiple network interfaces).
### Option: `port`
The port the AirSonos server will expose itself on. The default `49152` should
be fine in most cases. Only change this if you really have to.
### Option: `latency_rtp`
Allows you to tweak the buffering, which is needed when the audio is stuttering
(e.g., low-quality network). This option specifies the number of ms the addon
has to buffer the RTP audio (AirPlay). Setting this value below 500ms is not
recommended!
### Option: `latency_http`
Allows you to tweak the buffering, which is needed when the audio is stuttering
(e.g., low-quality network). This option specifies the number of ms the addon
has to buffer the HTTP audio.
### Option: `drift`
Set to `true` to let timing reference drift (no click).
## Sonos hints and limitations
When a Sonos group is created, only the master of that group will appear as
an AirPlay player and others will be removed if they were already detected.
If the group is later split, then individual players will re-appear.
Each detection cycle takes ~30 seconds.
Volume is set for the whole group, but the same level applies to all members.
If you need to change individual volumes, you need to use a Sonos native
controller. **Note**: these will be overridden if the group volume is later
changed again from an AirPlay device.
## Latency options explained
These bridges receive real-time "synchronous" audio from the AirPlay controller
in the format of RTP frames and forward it to the Sonos player in an HTTP
"asynchronous" continuous audio binary format. In other words,
the AirPlay clients "push" the audio using RTP and the Sonos players
"pull" the audio using an HTTP GET request.
A player using HTTP to get its audio expects to receive an initial large
portion of audio as the response to its GET and this creates a large enough
buffer to handle most further network congestion/delays. The rest of the audio
transmission is regulated by the player using TCP flow control. However, when
the source is an AirPlay RTP device, there is no such significant portion of
audio available in advance to be sent to the Player, as the audio comes to the
bridge in real time. Every 8ms, an RTP frame is received and is immediately
forwarded as the continuation of the HTTP body. If the Sonos player
starts to play immediately the first received audio sample, expecting an initial
burst to follow, then any network congestion delaying RTP audio will starve
the player and create shuttering.
The `latency_http` option allows a certain amount of silence frames to be sent
to the Sonos player, in a burst at the beginning. Then, while this
"artificial" silence is being played, it is possible for the bridge to build
a buffer of RTP frames that will then hide network delays that might happen
in further RTP frames transmission. This delays the start of the playback
by `latency_http` ms.
However, RTP frames are transmitted using UDP, which means there is no guarantee
of delivery, so frames might be lost from time to time
(often happens on WiFi networks). To allow detection of lost frames, they are
numbered sequentially (1,2 ... n) so every time two received frames are not
consecutive, the missing ones can be asked again by the AirPlay receiver.
Typically, the bridge forwards immediately every RTP frame using HTTP and again,
in HTTP, the notion of frame numbers does not exist, it is just the continuous
binary audio. So it is not possible to send audio non-sequentially when using
HTTP.
For example, if received RTP frames are numbered 1,2,3,6, this bridge will
forward (once decoded and transformed into raw audio) 1,2,3 immediately using
HTTP but when it receives 6, it will re-ask for 4 and 5 to be resent and
hold 6 while waiting (if 6 was transmitted immediately, the Sonos
will play 1,2,3,6 ... not nice).
The `latency_rtp` option sets for how long frame 6 shall be held before adding
two silence frames for 4 and 5 and send sending 4,5,6. Obviously, if this delay
is larger than the buffer in the Sonos player, playback will stop by
lack of audio. Note that `latency_rtp` does not delay playback start.
> **Note**: `latency_rtp` and `latency_http` could have been merged into a
> single `latency` parameter which would have set the max RTP frames holding time
> as well as the duration of the initial additional silence (delay),
> however, all Sonos devices do properly their own buffering of HTTP audio
> (i.e., they wait until they have received a certain amount of audio before
> starting to play), then adding silence would have introduced an extra
> unnecessary delay in playback.
## Tweaking AirSonos
AirSonos creates a configuration file called `airsonos.xml` in your Home
Assistant configuration directory. This file allows you to tweak each device
separately. Every time it finds a new device, it will be added to that file.
> **NOTE**: It is HIGHLY recommended to stop the addon before making changes
> to the configuration file manually.
## Known issues and limitations
- This add-on does support ARM-based devices, nevertheless, they must
at least be an ARMv7 device. (Raspberry Pi 1 and Zero is not supported).
## Changelog & Releases
This repository keeps a change log using [GitHub's releases][releases]
functionality.
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 Add-ons Discord chat server][discord] for add-on
support and feature requests.
- The [Home Assistant Discord chat server][discord-ha] for general Home
Assistant discussions and questions.
- The Home Assistant [Community Forum][forum].
- Join the [Reddit subreddit][reddit] in [/r/homeassistant][reddit]
You could also [open an issue here][issue] GitHub.
## 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].
## License
MIT License
Copyright (c) 2017-2021 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.
[commits]: https://github.com/hassio-addons/addon-airsonos/commits/main
[contributors]: https://github.com/hassio-addons/addon-airsonos/graphs/contributors
[discord-ha]: https://discord.gg/c5DvZ4e
[discord]: https://discord.me/hassioaddons
[forum]: https://community.home-assistant.io/t/home-assistant-community-add-on-airsonos/36796?u=frenck
[frenck]: https://github.com/frenck
[issue]: https://github.com/hassio-addons/addon-airsonos/issues
[reddit]: https://reddit.com/r/homeassistant
[releases]: https://github.com/hassio-addons/addon-airsonos/releases
[semver]: http://semver.org/spec/v2.0.0.htm

View File

@@ -1,37 +0,0 @@
# Home Assistant Community Add-on: AirSonos
[![Release][release-shield]][release] ![Project Stage][project-stage-shield] ![Project Maintenance][maintenance-shield]
[![Discord][discord-shield]][discord] [![Community Forum][forum-shield]][forum]
[![Sponsor Frenck via GitHub Sponsors][github-sponsors-shield]][github-sponsors]
[![Support Frenck on Patreon][patreon-shield]][patreon]
AirPlay capabilities for your Sonos (and UPnP) players.
## About
Apple devices use AirPlay to send audio to other devices, but this is not
compatible with Sonos players. This add-on tries to solve this
compatibility gap.
It detects Sonos players in your network and creates virtual AirPlay
devices for each of them. It acts as a bridge between the AirPlay client
and the real Sonos device.
Since Sonos uses UPnP, the add-on might also work for other UPnP players
(e.g., newer Samsung televisions).
[discord-shield]: https://img.shields.io/discord/478094546522079232.svg
[discord]: https://discord.me/hassioaddons
[forum-shield]: https://img.shields.io/badge/community-forum-brightgreen.svg
[forum]: https://community.home-assistant.io/t/home-assistant-community-add-on-airsonos/36796?u=frenck
[github-sponsors-shield]: https://frenck.dev/wp-content/uploads/2019/12/github_sponsor.png
[github-sponsors]: https://github.com/sponsors/frenck
[maintenance-shield]: https://img.shields.io/maintenance/yes/2021.svg
[patreon-shield]: https://frenck.dev/wp-content/uploads/2019/12/patreon.png
[patreon]: https://www.patreon.com/frenck
[project-stage-shield]: https://img.shields.io/badge/project%20stage-production%20ready-brightgreen.svg
[release-shield]: https://img.shields.io/badge/version-v3.1.1-blue.svg
[release]: https://github.com/hassio-addons/addon-airsonos/tree/v3.1.1

View File

@@ -1,35 +0,0 @@
{
"name": "AirSonos",
"version": "3.1.1",
"slug": "airsonos",
"description": "AirPlay capabilities for your Sonos (and UPnP) devices.",
"url": "https://github.com/hassio-addons/addon-airsonos",
"startup": "services",
"init": false,
"arch": [
"aarch64",
"amd64",
"armv7",
"i386"
],
"hassio_api": true,
"host_network": true,
"map": [
"config:rw"
],
"options": {
"port": 49152,
"latency_rtp": 1000,
"latency_http": 2000,
"drift": false
},
"schema": {
"log_level": "list(trace|debug|info|notice|warning|error|fatal)?",
"address": "str?",
"port": "port",
"latency_rtp": "int",
"latency_http": "int",
"drift": "bool"
},
"image": "ghcr.io/hassio-addons/airsonos/{arch}"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

View File

@@ -1,33 +0,0 @@
---
configuration:
log_level:
name: Log level
description: >-
Controls the level of log details the add-on provides.
port:
name: Port
description: >-
The port to run on, the default of 49152 should be good for most cases.
address:
name: Address
description: >-
Allows you to specify the IP address the AirCast server needs to
bind to.
latency_rtp:
name: RTP Latency
description: >-
Allows you to tweak the buffering, which is needed when the audio is
stuttering (e.g., low-quality network). This option specifies the number
of ms the add-on has to buffer the RTP audio (AirPlay). Setting this value
below 500ms is not recommended! Setting the value to 0 makes the add-on
to get the value from AirPlay.
latency_http:
name: HTTP Latency
description: >-
Allows you to tweak the buffering, which is needed when the audio is
stuttering (e.g., low-quality network). This option specifies the number
of ms the add-on has to buffer the HTTP audio.
drift:
name: Drift
description: >-
Allow to let timing reference drift (no click).

View File

@@ -1,16 +0,0 @@
# Changelog
## 2.1.1
- bump hassio-addon-base to V10.0.1
## 2.1.0
- bump hassio-addon-base to V10.0.0
## 2.0.3
- Enable Apache Foreground Logging
## 2.0.2
- ability to set a username and password to access the webfiles
## 2.0.0
- Initial release of the minimal Version

View File

@@ -1,20 +0,0 @@
ARG BUILD_FROM=ghcr.io/hassio-addons/base/amd64:10.0.1
# hadolint ignore=DL3006
FROM ${BUILD_FROM}
ENV LANG C.UTF-8
# Create directory for apache2 to store PID file
RUN mkdir /run/apache2
RUN apk --no-cache add apache2 libxml2-dev apache2-utils apache2-mod-wsgi apache2-ssl
#Configure Logging
RUN sed -i -r 's@Errorlog .*@Errorlog /dev/stderr@i' /etc/apache2/httpd.conf
RUN echo "Transferlog /dev/stdout" >> /etc/apache2/httpd.conf
# Copy data for add-on
COPY run.sh /
COPY index.html /
RUN chmod a+x /run.sh
RUN chmod a+x /index.html
CMD [ "/run.sh" ]

View File

@@ -1,2 +0,0 @@
Have a look at the README for Apache2 full Addon for more informations.
[README](https://github.com/FaserF/hassio-addons/blob/master/apache2/README.md)

View File

@@ -1,9 +0,0 @@
{
"build_from": {
"aarch64": "ghcr.io/hassio-addons/base/aarch64:10.0.1",
"amd64": "ghcr.io/hassio-addons/base/amd64:10.0.1",
"armhf": "ghcr.io/hassio-addons/base/armhf:10.0.1",
"armv7": "ghcr.io/hassio-addons/base/armv7:10.0.1",
"i386": "ghcr.io/hassio-addons/base/i386:10.0.1"
}
}

View File

@@ -1,42 +0,0 @@
{
"name": "Apache2 Minimal",
"version": "2.1.1",
"slug": "apache2-minimal",
"description": "Webserver without PHP and minimal extra modules",
"url": "https://github.com/FaserF/hassio-addons/tree/master/apache2-minimal",
"arch": ["armhf", "armv7", "aarch64", "amd64", "i386"],
"startup": "application",
"boot": "auto",
"webui": "[PROTO:ssl]://[HOST]:[PORT:80]",
"map": ["share:rw", "media:rw", "ssl"],
"ingress": true,
"panel_icon": "mdi:web-box",
"options": {
"document_root": "/share/htdocs",
"default_conf": "default",
"default_ssl_conf": "default",
"website_name":null,
"ssl": true,
"certfile": "fullchain.pem",
"keyfile": "privkey.pem"
},
"schema": {
"document_root":"str",
"default_conf":"str",
"default_ssl_conf":"str",
"website_name":"str",
"username":"str?",
"password":"str?",
"ssl": "bool",
"certfile": "str",
"keyfile": "str"
},
"ports": {
"80/tcp": 80,
"443": 443
},
"ports_description": {
"80/tcp": "Web interface http",
"443/tcp": "SSL Web interface"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

View File

@@ -1,284 +0,0 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<!--
Modified from the Debian original for Ubuntu
Last updated: 2014-03-19
See: https://launchpad.net/bugs/1288690
-->
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Apache2 FaserF Homeassistant Addon Default Page: It works</title>
<style type="text/css" media="screen">
* {
margin: 0px 0px 0px 0px;
padding: 0px 0px 0px 0px;
}
body, html {
padding: 3px 3px 3px 3px;
background-color: #D8DBE2;
font-family: Verdana, sans-serif;
font-size: 11pt;
text-align: center;
}
div.main_page {
position: relative;
display: table;
width: 800px;
margin-bottom: 3px;
margin-left: auto;
margin-right: auto;
padding: 0px 0px 0px 0px;
border-width: 2px;
border-color: #212738;
border-style: solid;
background-color: #FFFFFF;
text-align: center;
}
div.page_header {
height: 99px;
width: 100%;
background-color: #F5F6F7;
}
div.page_header span {
margin: 15px 0px 0px 50px;
font-size: 180%;
font-weight: bold;
}
div.page_header img {
margin: 3px 0px 0px 40px;
border: 0px 0px 0px;
}
div.table_of_contents {
clear: left;
min-width: 200px;
margin: 3px 3px 3px 3px;
background-color: #FFFFFF;
text-align: left;
}
div.table_of_contents_item {
clear: left;
width: 100%;
margin: 4px 0px 0px 0px;
background-color: #FFFFFF;
color: #000000;
text-align: left;
}
div.table_of_contents_item a {
margin: 6px 0px 0px 6px;
}
div.content_section {
margin: 3px 3px 3px 3px;
background-color: #FFFFFF;
text-align: left;
}
div.content_section_text {
padding: 4px 8px 4px 8px;
color: #000000;
font-size: 100%;
}
div.content_section_text pre {
margin: 8px 0px 8px 0px;
padding: 8px 8px 8px 8px;
border-width: 1px;
border-style: dotted;
border-color: #000000;
background-color: #F5F6F7;
font-style: italic;
}
div.content_section_text p {
margin-bottom: 6px;
}
div.content_section_text ul, div.content_section_text li {
padding: 4px 8px 4px 16px;
}
div.section_header {
padding: 3px 6px 3px 6px;
background-color: #8E9CB2;
color: #FFFFFF;
font-weight: bold;
font-size: 112%;
text-align: center;
}
div.section_header_red {
background-color: #CD214F;
}
div.section_header_grey {
background-color: #9F9386;
}
.floating_element {
position: relative;
float: left;
}
div.table_of_contents_item a,
div.content_section_text a {
text-decoration: none;
font-weight: bold;
}
div.table_of_contents_item a:link,
div.table_of_contents_item a:visited,
div.table_of_contents_item a:active {
color: #000000;
}
div.table_of_contents_item a:hover {
background-color: #000000;
color: #FFFFFF;
}
div.content_section_text a:link,
div.content_section_text a:visited,
div.content_section_text a:active {
background-color: #DCDFE6;
color: #000000;
}
div.content_section_text a:hover {
background-color: #000000;
color: #DCDFE6;
}
div.validator {
}
</style>
</head>
<body>
<div class="main_page">
<div class="page_header floating_element">
<span class="floating_element">
Apache2 FaserF Homeassistant Addon Default Page
</span>
</div>
<!-- <div class="table_of_contents floating_element">
<div class="section_header section_header_grey">
TABLE OF CONTENTS
</div>
<div class="table_of_contents_item floating_element">
<a href="#about">About</a>
</div>
<div class="table_of_contents_item floating_element">
<a href="#changes">Changes</a>
</div>
<div class="table_of_contents_item floating_element">
<a href="#scope">Scope</a>
</div>
<div class="table_of_contents_item floating_element">
<a href="#files">Config files</a>
</div>
</div>
-->
<div class="content_section floating_element">
<div class="section_header section_header_red">
<div id="about"></div>
It works!
</div>
<div class="content_section_text">
<p>
This is the default welcome page used to test the correct
operation of the Apache2 server after the installation of the Homeassistant Addon.
If you can read this page, it means that the Apache HTTP server installed at
this site is working properly. You should <b>replace this file</b> (located at
<tt>/share/htdocs/index.html</tt>) before continuing to operate your HTTP server.
</p>
<p>
If you are a normal user of this web site and don't know what this page is
about, this probably means that the site is currently unavailable due to
maintenance.
If the problem persists, please contact the site's administrator.
</p>
</div>
<div class="section_header">
<div id="changes"></div>
Configuration Overview
</div>
<div class="content_section_text">
<p>
The configuration system is <b>fully documented in
the github repository</b>. Refer to this for the full
documentation. Documentation can be
found by accessing the <a href="https://github.com/FaserF/hassio-addons/tree/master/apache2">manual</a>.
</p>
</div>
<div class="section_header">
<div id="bugs"></div>
Reporting Problems
</div>
<div class="content_section_text">
<p>
Please use the <tt>github issues tracker</tt> tool to report bugs in the
Apache2 Addon with Homeassistant. However, check <a
href="https://github.com/FaserF/hassio-addons/issues">existing
bug reports</a> before reporting a new bug.
</p>
<p>
Please report bugs specific to modules (such as PHP and others)
to respective packages, not to the web server itself.
</p>
</div>
</div>
</div>
<div class="validator">
<p>
<a href="https://validator.w3.org/check?uri=referer"><img src="https://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0 Transitional" height="31" width="88" /></a>
</p>
</div>
</body>
</html>

View File

@@ -1,166 +0,0 @@
#!/usr/bin/env bashio
ssl=$(bashio::config 'ssl')
website_name=$(bashio::config 'website_name')
certfile=$(bashio::config 'certfile')
keyfile=$(bashio::config 'keyfile')
DocumentRoot=$(bashio::config 'document_root')
phpini=$(bashio::config 'php_ini')
username=$(bashio::config 'username')
password=$(bashio::config 'password')
default_conf=$(bashio::config 'default_conf')
default_ssl_conf=$(bashio::config 'default_ssl_conf')
webrootdocker=/var/www/localhost/htdocs/
if [ $phpini = "get_file" ]; then
cp /etc/php7/php.ini /share/apache2addon_php.ini
echo "You have requestet a copy of the php.ini file. You will now find your copy at /share/apache2addon_php.ini"
echo "Addon will now be stopped. Please remove the config option and change it to the name of your new config file (for example /share/php.ini)"
exit 1
fi
rm -r $webrootdocker
if [ ! -d $DocumentRoot ]; then
echo "You haven't put your website to $DocumentRoot"
echo "A default website will now be used"
mkdir $webrootdocker
cp /index.html $webrootdocker
else
#Create Shortcut to shared html folder
ln -s $DocumentRoot /var/www/localhost/htdocs
fi
#Set rights to web folders and create user
find $DocumentRoot -type d -exec chmod 771 {} \;
if [ ! -z "$username" ] && [ ! -z "$password" ] && [ ! $username = "null" ] && [ ! $password = "null" ]; then
adduser -S $username -G www-data
echo "$username:$password" | chpasswd $username
find $webrootdocker -type d -exec chown $username:www-data -R {} \;
find $webrootdocker -type f -exec chown $username:www-data -R {} \;
else
echo "No username and/or password was provided. Skipping account set up."
fi
if [ $phpini != "default" ]; then
if [ -f $phpini ]; then
echo "Your custom php.ini at $phpini will be used."
rm /etc/php7/php.ini
cp $phpini /etc/php7/php.ini
else
echo "You have changed the php_ini variable, but the new file could not be found! Default php.ini file will be used instead."
fi
fi
if [ $ssl = "true" ] && [ $default_conf = "default" ]; then
echo "You have activated SSL. SSL Settings will be applied"
if [ ! -f /ssl/$certfile ]; then
echo "Cannot find certificate file $certfile"
exit 1
fi
if [ ! -f /ssl/$keyfile ]; then
echo "Cannot find certificate key file $keyfile"
exit 1
fi
mkdir /etc/apache2/sites-enabled
sed -i '/LoadModule rewrite_module/s/^#//g' /etc/apache2/httpd.conf
echo "Listen 8099" >> /etc/apache2/httpd.conf
echo "<VirtualHost *:80>" > /etc/apache2/sites-enabled/000-default.conf
echo "ServerName $website_name" >> /etc/apache2/sites-enabled/000-default.conf
echo "ServerAdmin webmaster@localhost" >> /etc/apache2/sites-enabled/000-default.conf
echo "DocumentRoot $webrootdocker" >> /etc/apache2/sites-enabled/000-default.conf
echo "#Redirect http to https" >> /etc/apache2/sites-enabled/000-default.conf
echo " RewriteEngine On" >> /etc/apache2/sites-enabled/000-default.conf
echo " RewriteCond %{HTTPS} off" >> /etc/apache2/sites-enabled/000-default.conf
echo " RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}" >> /etc/apache2/sites-enabled/000-default.conf
echo "#End Redirect http to https" >> /etc/apache2/sites-enabled/000-default.conf
echo " ErrorLog /var/log/error.log" >> /etc/apache2/sites-enabled/000-default.conf
echo " #CustomLog /var/log/access.log combined" >> /etc/apache2/sites-enabled/000-default.conf
echo "</VirtualHost>" >> /etc/apache2/sites-enabled/000-default.conf
echo "<IfModule mod_ssl.c>" > /etc/apache2/sites-enabled/000-default-le-ssl.conf
echo "<VirtualHost *:443>" >> /etc/apache2/sites-enabled/000-default-le-ssl.conf
echo "ServerName $website_name" >> /etc/apache2/sites-enabled/000-default-le-ssl.conf
echo "ServerAdmin webmaster@localhost" >> /etc/apache2/sites-enabled/000-default-le-ssl.conf
echo "DocumentRoot $webrootdocker" >> /etc/apache2/sites-enabled/000-default-le-ssl.conf
echo " ErrorLog /var/log/error.log" >> /etc/apache2/sites-enabled/000-default-le-ssl.conf
echo " #CustomLog /var/log/access.log combined" >> /etc/apache2/sites-enabled/000-default-le-ssl.conf
echo "SSLCertificateFile /ssl/$certfile" >> /etc/apache2/sites-enabled/000-default-le-ssl.conf
echo "SSLCertificateKeyFile /ssl/$keyfile" >> /etc/apache2/sites-enabled/000-default-le-ssl.conf
echo "</VirtualHost>" >> /etc/apache2/sites-enabled/000-default-le-ssl.conf
echo "</IfModule>" >> /etc/apache2/sites-enabled/000-default-le-ssl.conf
else
echo "SSL is deactivated and/or you are using a custom config."
fi
if [ "$ssl" = "true" ] || [ "$default_conf" != "default" ]; then
echo "Include /etc/apache2/sites-enabled/*.conf" >> /etc/apache2/httpd.conf
fi
sed -i -e '/AllowOverride/s/None/All/' /etc/apache2/httpd.conf
if [ "$default_conf" = "get_config" ]; then
if [ -f /etc/apache2/sites-enabled/000-default.conf ]; then
if [ ! -d /etc/apache2/sites-enabled ]; then
mkdir /etc/apache2/sites-enabled
fi
cp /etc/apache2/sites-enabled/000-default.conf /share/000-default.conf
echo "You have requested a copy of the apache2 config. You can now find it at /share/000-default.conf ."
fi
if [ -f /etc/apache2/httpd.conf ]; then
cp /etc/apache2/httpd.conf /share/httpd.conf
echo "You have requested a copy of the apache2 config. You can now find it at /share/httpd.conf ."
fi
if [ "$default_ssl_conf" != "get_config" ]; then
echo "Exiting now..."
exit 0
fi
fi
if [[ ! $default_conf =~ ^(default|get_config)$ ]]; then
if [ -f $default_conf ]; then
if [ ! -d /etc/apache2/sites-enabled ]; then
mkdir /etc/apache2/sites-enabled
fi
if [ -f /etc/apache2/sites-enabled/000-default.conf ]; then
rm /etc/apache2/sites-enabled/000-default.conf
fi
cp -rf $default_conf /etc/apache2/sites-enabled/000-default.conf
echo "Your custom apache config at $default_conf will be used."
else
echo "Cant find your custom 000-default.conf file $default_conf - be sure you have choosen the full path. Exiting now..."
exit 1
fi
fi
if [ "$default_ssl_conf" = "get_config" ]; then
if [ -f /etc/apache2/httpd.conf ]; then
cp /etc/apache2/sites-enabled/000-default-le-ssl.conf /share/000-default-le-ssl.conf
echo "You have requested a copy of the apache2 ssl config. You can now find it at /share/000-default-le-ssl.conf ."
fi
echo "Exiting now..."
exit 0
fi
if [ "$default_ssl_conf" != "default" ]; then
if [ -f $default_ssl_conf ]; then
if [ ! -d /etc/apache2/sites-enabled ]; then
mkdir /etc/apache2/sites-enabled
fi
if [ -f /etc/apache2/sites-enabled/000-default-le-ssl.conf ]; then
rm /etc/apache2/sites-enabled/000-default-le-ssl.conf
fi
cp -rf $default_ssl_conf /etc/apache2/sites-enabled/000-default-le-ssl.conf
echo "Your custom apache config at $default_ssl_conf will be used."
else
echo "Cant find your custom 000-default-le-ssl.conf file $default_ssl_conf - be sure you have choosen the full path. Exiting now..."
exit 1
fi
fi
echo "Here is your web file architecture."
ls -l $webrootdocker
echo "Starting Apache2..."
exec /usr/sbin/httpd -D FOREGROUND

View File

@@ -1,84 +0,0 @@
# Changelog
## 2.1.1
- bump hassio-addon-base to V10.0.1
## 2.1.0
- bump hassio-addon-base to V10.0.0
- fixed an issue in the php7-locales which resulted in an issue while installing the addon
## 2.0.4
- add php7-ctype support
## 2.0.3
- Enable Apache Foreground Logging
## 2.0.2
- ability to set a username and password to access the webfiles
## 2.0.1
- add php7-locales support
- add Mosquitto-PHP support
## 2.0.0
- add php7-xml support
- this addon is now available in three variants:
Minimal
Minimal with MariaDB
this "normal" version with common used PHP Modules
## 1.7.2
- fixed error: can't find custom config
## 1.7.1
- fixed error: can't find custom web root folder
## 1.7.0
- add php7-session php7-intl php7-soap php7-session php7-fileinfo support
## 1.6.0
- add php7-iconv and php7-dom support
## 1.5.1
- add option to recieve a apache2 config copy
- fix PHP7-PDO syntax error in Dockerfile
## 1.5.0
- add PHP7-PDO package
## 1.4.0
- allow the usage of custom apache2 config files
## 1.3.0
- allow the usage of a custom php.ini file
## 1.2.3
- add /media folder as a root folder option
## 1.2.2
- hotfix update for ssl path not working
## 1.2.1
- enabled use of .htaccess files
## 1.2.0
- new option document_root -> Allowing the user to decide the document root folder
- added default index.html if the user has no webfiles in the correct folder
## 1.1.2
- added php-mcrypt, php-zip
- Ingress is now supported
## 1.1.1
- added mariadb-client to docker image
## 1.1.0
- New Icon
- Prepared Ingress Support
## 1.0.1
- Fixed SSL
- Removed MariaDB Options
## 1.0.0
- Initial release

View File

@@ -1,41 +0,0 @@
ARG BUILD_FROM=ghcr.io/hassio-addons/base/amd64:10.0.1
# hadolint ignore=DL3006
FROM ${BUILD_FROM}
ENV LANG C.UTF-8
# Create directory for apache2 to store PID file
RUN mkdir /run/apache2
RUN apk --no-cache add apache2 php7-apache2 libxml2-dev apache2-utils apache2-mod-wsgi apache2-ssl
RUN apk --no-cache add php7 php7-dev php7-fpm php7-mysqli php7-opcache php7-gd php7-zlib php7-curl php7-phar php7-json php7-mbstring php7-mcrypt php7-zip php7-pdo php7-pdo_mysql php7-iconv php7-dom php7-session php7-intl php7-soap php7-fileinfo php7-xml php7-ctype
RUN apk --no-cache add mosquitto mosquitto-dev
RUN apk --no-cache add mariadb-client
#musl-locales/php7-locales
RUN apk add --no-cache cmake make musl-dev gcc gettext-dev libintl
RUN wget https://gitlab.com/rilian-la-te/musl-locales/-/archive/master/musl-locales-master.zip \
&& unzip musl-locales-master.zip \
&& cd musl-locales-master \
&& cmake -DLOCALE_PROFILE=OFF -D CMAKE_INSTALL_PREFIX:PATH=/usr . && make && make install \
&& cd .. && rm -r musl-locales-master
#Mosquitto-PHP
RUN wget https://github.com/mgdm/Mosquitto-PHP/archive/refs/heads/master.zip \
&& unzip master.zip \
&& cd Mosquitto-PHP-master \
&& phpize \
&& ./configure \
&& make \
&& make install \
&& cd .. && rm -r Mosquitto-PHP-master
#Configure Logging
RUN sed -i -r 's@Errorlog .*@Errorlog /dev/stderr@i' /etc/apache2/httpd.conf
RUN echo "Transferlog /dev/stdout" >> /etc/apache2/httpd.conf
# Copy data for add-on
COPY run.sh /
COPY index.html /
RUN chmod a+x /run.sh
RUN chmod a+x /index.html
CMD [ "/run.sh" ]

View File

@@ -1,175 +0,0 @@
# Home Assistant Community Add-on: Apache2
![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]
![Project Maintenance][maintenance-shield]
Apache2 Webserver for Homeassistant OS
![Ingress Support](images/ingress.png)
## About
The Apache HTTP Server Project is an effort to develop and maintain an open-source HTTP server for modern operating systems including UNIX and Windows. The goal of this project is to provide a secure, efficient and extensible server that provides HTTP services in sync with the current HTTP standards.<br />
The Apache HTTP Server ("httpd") was launched in 1995 and it has been the most popular web server on the Internet since April 1996. It has celebrated its 25th birthday as a project in February 2020.<br />
The Apache HTTP Server is a project of The Apache Software Foundation.
## Different Versions
### Full Version
The [full Apache2 Version](https://github.com/FaserF/hassio-addons/tree/master/apache2) with MariaDB and common used PHP modules. <br />
This docker image comes with: apache2 php7-apache2 libxml2-dev apache2-utils apache2-mod-wsgi apache2-ssl mariadb-client<br />
The following php7 extensions will be installed: php7 php7-dev php7-fpm php7-mysqli php7-opcache php7-gd php7-zlib php7-curl php7-phar php7-json php7-mbstring php7-mcrypt php7-zip php7-pdo php7-pdo_mysql php7-iconv php7-dom php7-session php7-intl php7-soap php7-fileinfo php7-xml<br />
And it comes with php7 locales and [Mosquitto-PHP](https://github.com/mgdm/Mosquitto-PHP).
### Minimal Version
The [Minimal Version](https://github.com/FaserF/hassio-addons/tree/master/apache2-minimal) of the Apache2 Addon without MariaDB and with no PHP modules. <br />
This docker image comes with: apache2 libxml2-dev apache2-utils apache2-mod-wsgi apache2-ssl
### Minimal Version with MariaDB
The [Minimal Version with MariaDB and some PHP modules](https://github.com/FaserF/hassio-addons/tree/master/apache2-minimal-mariadb) of the Apache2 Addon. <br />
This docker image comes with: apache2 php7-apache2 libxml2-dev apache2-utils apache2-mod-wsgi apache2-ssl mariadb-client<br />
The following php7 extensions will be installed: php7 php7-mysqli php7-opcache php7-curl php7-json php7-mbstring php7-mcrypt php7-zip
## Installation
[![FaserF Homeassistant Addons](https://my.home-assistant.io/badges/supervisor_add_addon_repository.svg)](https://my.home-assistant.io/redirect/supervisor_add_addon_repository/?repository_url=https%3A%2F%2Fgithub.com%2FFaserF%2Fhassio-addons)
<br />
The installation of this add-on is pretty straightforward and not different in comparison to installing any other custom Home Assistant add-on.<br />
Just click the link above or add my repo to the hassio addons repositorys: https://github.com/FaserF/hassio-addons
Put your website files to /share/htdocs<br />
Example File where your index.html should be: /share/htdocs/index.html <br />
If you want to integrate your website with a mariadb database. Please ensure that the MariaDB Addon is installed!
## Configuration
**Note**: _Remember to restart the add-on when the configuration is changed._
Example add-on configuration:
```yaml
document_root: /media/apache2
php_ini: /share/apache2/php.ini
default_conf: /share/apache2/000-default.conf
default_ssl_conf: get_file
website_name: itdoesntmatter_as_ssl_is_set_to_false
username: apache
password: mySecretPassword
ssl: false
certfile: itdoesntmatter_as_ssl_is_set_to_false
keyfile: itdoesntmatter_as_ssl_is_set_to_false
```
<br />
Recommended Example add-on configuration:
```yaml
document_root: /share/htdocs
php_ini: default
default_conf: default
default_ssl_conf: default
website_name: mywebsite.ddns.net
ssl: true
certfile: fullchain.pem
keyfile: privkey.pem
```
**Note**: _This is just an example, don't copy and paste it! Create your own!_
### Option: `document_root`
This option is needed. Change it depending where your root webfolder is on your homeassistant installation.
Note: it has to be somewhere in the /share or /media folder! Other folders are not visible to this addon.
### Option: `php_ini`
You can choose between the following options:
default -> the default php7 php.ini file will be used
get_file -> copies the default php7 php.ini file from the addon to /share/apache2addon_php.ini
path/to/your/new/php.ini -> Please change the location depending where your custom php.ini file is, f.e.: /share/apache2/php.ini
### Option: `default_conf` & `default_ssl_conf`
You can choose between the following options:
default -> the default apache2 addon file will be used
get_config -> Get a copy of the default apache2 addon config file to your /share folder.
path/to/your/new/apache2.conf -> Please change the location depending where your custom 000-default.conf / 000-default-le-ssl.conf file is, f.e.: /share/apache2/000-default.conf <br />
More Information: https://cwiki.apache.org/confluence/display/HTTPD/ExampleVhosts<br /> <br />
Please note, that I wont give any support if you are using custom apache2 config files and are recieving any apache2 errors!
### Option: `website_name`
This option is needed, if you enable ssl to true. If you are not using SSL put anything in here, as it doesnt matter.
### Option: `username`
This option is optional. Set a username to access the webfiles.
### Option: `password`
This option is optional. Set a password to access the webfiles.
### Option: `ssl`
Enables/Disables SSL (HTTPS) on the web interface. Set it `true` to enable it, `false` otherwise.
If you need a self-signed certificate, have a look at my openssl addon: https://github.com/FaserF/hassio-addons/tree/master/openssl
**Note**: _The files MUST be stored in `/ssl/`, which is the default_
## Ingress
This addon supports Homeassistant Ingress. Until now it seems only to work if you enable SSL!
And also I am sorry, but I cant support all your websites. Basic HTML Websites will work great with ingress, the more advanced the page is, the harder it is to support ingress.
## Support
Got questions or problems?
You can [open an issue here][issue] GitHub.
Please keep in mind, that this software is only tested on armv7 running on a Raspberry Pi 4.
## Authors & contributors
The original program is from the Apache Project. For more informatios please visit this page: https://httpd.apache.org/
The hassio addon is brought to you by [FaserF].
## License
MIT License
Copyright (c) 2019-2021 FaserF & The Apache Project
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.
[maintenance-shield]: https://img.shields.io/maintenance/yes/2021.svg
[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
[FaserF]: https://github.com/FaserF/
[issue]: https://github.com/FaserF/hassio-addons/issues

View File

@@ -1,9 +0,0 @@
{
"build_from": {
"aarch64": "ghcr.io/hassio-addons/base/aarch64:10.0.1",
"amd64": "ghcr.io/hassio-addons/base/amd64:10.0.1",
"armhf": "ghcr.io/hassio-addons/base/armhf:10.0.1",
"armv7": "ghcr.io/hassio-addons/base/armv7:10.0.1",
"i386": "ghcr.io/hassio-addons/base/i386:10.0.1"
}
}

View File

@@ -1,44 +0,0 @@
{
"name": "Apache2",
"version": "2.1.1",
"slug": "apache2",
"description": "OpenSource Webserver",
"url": "https://github.com/FaserF/hassio-addons/tree/master/apache2",
"arch": ["armhf", "armv7", "aarch64", "amd64", "i386"],
"startup": "application",
"boot": "auto",
"webui": "[PROTO:ssl]://[HOST]:[PORT:80]",
"map": ["share:rw", "media:rw", "ssl"],
"ingress": true,
"panel_icon": "mdi:web-box",
"options": {
"document_root": "/share/htdocs",
"php_ini": "default",
"default_conf": "default",
"default_ssl_conf": "default",
"website_name":null,
"ssl": true,
"certfile": "fullchain.pem",
"keyfile": "privkey.pem"
},
"schema": {
"document_root":"str",
"php_ini":"str",
"default_conf":"str",
"default_ssl_conf":"str",
"website_name":"str",
"username":"str?",
"password":"str?",
"ssl": "bool",
"certfile": "str",
"keyfile": "str"
},
"ports": {
"80/tcp": 80,
"443": 443
},
"ports_description": {
"80/tcp": "Web interface http",
"443/tcp": "SSL Web interface"
}
}

Some files were not shown because too many files have changed in this diff Show More