mirror of
https://github.com/Mesteriis/hassio-addons-avm.git
synced 2026-01-08 06:31:01 +01:00
v2
This commit is contained in:
28
.devcontainer/devcontainer.json
Normal file
28
.devcontainer/devcontainer.json
Normal 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
6
.github/.gitattributes
vendored
Normal 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
9
.github/.gitignore
vendored
Normal 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
1
.github/CODEOWNERS
vendored
@@ -1 +0,0 @@
|
||||
.github/* @frenck
|
||||
133
.github/CODE_OF_CONDUCT.md
vendored
133
.github/CODE_OF_CONDUCT.md
vendored
@@ -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
|
||||
29
.github/CONTRIBUTING.md
vendored
29
.github/CONTRIBUTING.md
vendored
@@ -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
2
.github/FUNDING.yml
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
---
|
||||
custom: https://buymeacoffee.com/mesteriisw
|
||||
20
.github/ISSUE_TEMPLATE.md
vendored
20
.github/ISSUE_TEMPLATE.md
vendored
@@ -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
60
.github/ISSUE_TEMPLATE/BUG-REPORT.yml
vendored
Normal 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
2
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
---
|
||||
blank_issues_enabled: false
|
||||
44
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
Normal file
44
.github/ISSUE_TEMPLATE/feature-request.yml
vendored
Normal 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
|
||||
41
.github/ISSUE_TEMPLATE/other-questions.md
vendored
Normal file
41
.github/ISSUE_TEMPLATE/other-questions.md
vendored
Normal 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.-->
|
||||
9
.github/PULL_REQUEST_TEMPLATE.md
vendored
9
.github/PULL_REQUEST_TEMPLATE.md
vendored
@@ -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
1839
.github/SECURITY.md
vendored
File diff suppressed because it is too large
Load Diff
13
.github/dependabot.yaml
vendored
13
.github/dependabot.yaml
vendored
@@ -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
10
.github/dependabot.yml
vendored
Normal 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
85
.github/labels.yml
vendored
@@ -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
10
.github/linters/.gitleaks.toml
vendored
Normal 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
8
.github/linters/.hadolint.yaml
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
ignored:
|
||||
- DL3002
|
||||
- DL3006
|
||||
- DL3007
|
||||
- DL3008
|
||||
- DL3009
|
||||
- DL3018
|
||||
9
.github/linters/.jscpd.json
vendored
Normal file
9
.github/linters/.jscpd.json
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"threshold": 0,
|
||||
"reporters": ["html", "markdown"],
|
||||
"ignore": [
|
||||
"**/.git/**",
|
||||
"**/*.md",
|
||||
"**/.github/**"
|
||||
]
|
||||
}
|
||||
35
.github/linters/.markdown-lint.yml
vendored
Normal file
35
.github/linters/.markdown-lint.yml
vendored
Normal 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
109
.github/paths-filter.yml
vendored
Normal 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
|
||||
65
.github/workflows/archived_lint-checks.yaml
vendored
Normal file
65
.github/workflows/archived_lint-checks.yaml
vendored
Normal 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
157
.github/workflows/daily_README.yaml
vendored
Normal 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=""
|
||||
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 ' README2.md; fi
|
||||
sed -i "$ADDONSLINE"'a   ' README2.md || true
|
||||
sed -i "$ADDONSLINE"'a ✓ '"$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
33
.github/workflows/daily_stale.yml
vendored
Normal 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
|
||||
242
.github/workflows/helper_stats_graphs.yaml
vendored
Normal file
242
.github/workflows/helper_stats_graphs.yaml
vendored
Normal 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
|
||||
22
.github/workflows/labels.yaml
vendored
22
.github/workflows/labels.yaml
vendored
@@ -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 }}
|
||||
33
.github/workflows/lint.yaml
vendored
33
.github/workflows/lint.yaml
vendored
@@ -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
|
||||
21
.github/workflows/lock.yaml
vendored
21
.github/workflows/lock.yaml
vendored
@@ -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
69
.github/workflows/on_issues.yml
vendored
Normal 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 ## ⚠ Open Issue : [$TITLE (opened ${DATEISSUE})]($URL) by [@${REQ}](https://github.com/$REQ)" "$f"/README.md
|
||||
elif [[ "$LABEL" == *"enhancement"* ]]; then
|
||||
sed -i "1i ## ⚠ 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
40
.github/workflows/onpr_automerge.yaml
vendored
Normal 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
276
.github/workflows/onpr_check-pr.yaml
vendored
Normal 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
232
.github/workflows/onpush_builder.yaml
vendored
Normal 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
|
||||
32
.github/workflows/onpush_superlinter.yml
vendored
Normal file
32
.github/workflows/onpush_superlinter.yml
vendored
Normal 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
|
||||
54
.github/workflows/repository-updater.yaml
vendored
54
.github/workflows/repository-updater.yaml
vendored
@@ -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 }}
|
||||
40
.github/workflows/stale.yaml
vendored
40
.github/workflows/stale.yaml
vendored
@@ -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.
|
||||
75
.github/workflows/translations-download.yaml
vendored
75
.github/workflows/translations-download.yaml
vendored
@@ -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 }}
|
||||
53
.github/workflows/translations-upload.yaml
vendored
53
.github/workflows/translations-upload.yaml
vendored
@@ -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 }}
|
||||
76
.github/workflows/weekly-supelinter.yaml
vendored
Normal file
76
.github/workflows/weekly-supelinter.yaml
vendored
Normal 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
36
.github/workflows/weekly_addons_updater
vendored
Normal 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
|
||||
43
.github/workflows/weekly_bashbeautify.yaml
vendored
Normal file
43
.github/workflows/weekly_bashbeautify.yaml
vendored
Normal 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
54
.github/workflows/weekly_crlftolf.yaml
vendored
Normal 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
|
||||
37
.github/workflows/weekly_reduceimagesize.yml
vendored
Normal file
37
.github/workflows/weekly_reduceimagesize.yml
vendored
Normal 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 can’t 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
31
.github/workflows/weekly_sortjson.yaml
vendored
Normal 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
106
.github/workflows/weekly_stats.yaml
vendored
Normal 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
|
||||
103
.templates/.README.md
Normal file
103
.templates/.README.md
Normal 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)
|
||||

|
||||
|
||||
[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
|
||||
|
||||
[](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)
|
||||
[](https://github.com/Mesteriis/hassio-addons-avm/actions/workflows/weekly-supelinter.yaml)
|
||||
[](https://github.com/Mesteriis/hassio-addons-avm/actions/workflows/onpush_builder.yaml)
|
||||
[](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!_
|
||||
|
||||
[](https://github.com/Mesteriis/hassio-addons-avm/stargazers)
|
||||
|
||||
_Thanks to all contributors !_
|
||||
|
||||
[](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
|
||||
51
.templates/00-aaa_dockerfile_backup.sh
Executable file
51
.templates/00-aaa_dockerfile_backup.sh
Executable 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
61
.templates/00-banner.sh
Executable 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
|
||||
8
.templates/00-bettercomments.sh
Executable file
8
.templates/00-bettercomments.sh
Executable file
@@ -0,0 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Color comments
|
||||
#! Red
|
||||
#? Question
|
||||
#// Done
|
||||
#todo To do
|
||||
#* Green
|
||||
19
.templates/00-deprecated.sh
Executable file
19
.templates/00-deprecated.sh
Executable 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
101
.templates/00-global_var.sh
Executable 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
103
.templates/00-local_mounts.sh
Executable 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
276
.templates/00-smb_mounts.sh
Executable 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
200
.templates/01-config_yaml.sh
Executable 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/Add‐ons-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
66
.templates/01-custom_script.sh
Executable 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
46
.templates/19-json_repair.sh
Executable 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
|
||||
35
.templates/90-disable_ingress.sh
Executable file
35
.templates/90-disable_ingress.sh
Executable 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
44
.templates/90-dns_set.sh
Executable 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
14
.templates/91-silent.sh
Executable 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
|
||||
172
.templates/91-universal_graphic_drivers.sh
Executable file
172
.templates/91-universal_graphic_drivers.sh
Executable 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
10
.templates/99-custom_script.sh
Executable 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
|
||||
10
.templates/config.template
Normal file
10
.templates/config.template
Normal 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
28
.templates/ha_autoapps.sh
Executable 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
|
||||
275
.templates/ha_automatic_packages.sh
Executable file
275
.templates/ha_automatic_packages.sh
Executable 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
36
.templates/ha_automodules.sh
Executable 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
59
.templates/ha_entrypoint.sh
Executable 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
|
||||
60
.templates/ha_entrypoint_modif.sh
Executable file
60
.templates/ha_entrypoint_modif.sh
Executable 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
59
.templates/ha_lsio.sh
Executable 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
|
||||
9
.templates/script.template
Normal file
9
.templates/script.template
Normal 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
|
||||
9
.templates/show_text_color
Normal file
9
.templates/show_text_color
Normal 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"
|
||||
66
.yamllint
66
.yamllint
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
## What’s 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)
|
||||
231
aircast/DOCS.md
231
aircast/DOCS.md
@@ -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
|
||||
@@ -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
|
||||
@@ -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}"
|
||||
}
|
||||
BIN
aircast/icon.png
BIN
aircast/icon.png
Binary file not shown.
|
Before Width: | Height: | Size: 2.4 KiB |
BIN
aircast/logo.png
BIN
aircast/logo.png
Binary file not shown.
|
Before Width: | Height: | Size: 12 KiB |
@@ -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).
|
||||
@@ -1,15 +0,0 @@
|
||||
## What’s 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)
|
||||
245
airsonos/DOCS.md
245
airsonos/DOCS.md
@@ -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
|
||||
@@ -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
|
||||
@@ -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 |
@@ -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).
|
||||
@@ -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
|
||||
@@ -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" ]
|
||||
@@ -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)
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -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 |
@@ -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>
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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" ]
|
||||
@@ -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
|
||||
|
||||

|
||||
|
||||
## 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
|
||||
|
||||
[](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
|
||||
@@ -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"
|
||||
}
|
||||
}
|
||||
@@ -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
Reference in New Issue
Block a user