From 058b2a448c5e65685182cb1eb58488d3236360ca Mon Sep 17 00:00:00 2001 From: Carlo Mion Date: Thu, 16 Mar 2023 14:17:52 +0100 Subject: [PATCH 01/12] refactor(asterisk.sh): read configuration options from a JSON file, in addition to the supervisor API Allow to run the add-on without the supervisor. Refactor get_persons() function to be invoked only if `auto_add` is true. Use `bashio:jq` to extract options from the JSON configuration file. --- asterisk/Dockerfile | 5 ++ asterisk/rootfs/etc/cont-init.d/asterisk.sh | 66 +++++++++++++++---- .../rootfs/etc/cont-init.d/asterisk_mbox.sh | 19 ++++-- 3 files changed, 71 insertions(+), 19 deletions(-) diff --git a/asterisk/Dockerfile b/asterisk/Dockerfile index ee9f073..836f4b9 100644 --- a/asterisk/Dockerfile +++ b/asterisk/Dockerfile @@ -6,6 +6,11 @@ FROM $BUILD_FROM AS base SHELL [ "/bin/bash", "-euxo", "pipefail", "-c" ] +# Add additional Debian APT mirror, since the default `deb.debian.org` randomly returns `502 connection timed out` +RUN echo $'deb http://ftp.it.debian.org/debian/ bullseye main \n\ +deb http://debian.mirror.garr.it/debian-security/ bullseye-security main \n\ +deb http://ftp.it.debian.org/debian/ bullseye-updates main' > /etc/apt/sources.list.d/mirror.list + # https://pypi.org/project/asterisk_mbox_server/#history ARG ASTERISK_MBOX_SERVER_VERSION="0.5.3" RUN export DEBIAN_FRONTEND=noninteractive; \ diff --git a/asterisk/rootfs/etc/cont-init.d/asterisk.sh b/asterisk/rootfs/etc/cont-init.d/asterisk.sh index cae442d..804cbfe 100755 --- a/asterisk/rootfs/etc/cont-init.d/asterisk.sh +++ b/asterisk/rootfs/etc/cont-init.d/asterisk.sh @@ -10,10 +10,20 @@ if ! bashio::fs.directory_exists '/config/asterisk'; then bashio::exit.nok 'Failed to create initial asterisk config folder' fi -bashio::log.info "Configuring certificate..." +# Try to read the configuration from the supervisor API. +# If the supervisor is not available (the function returns an empty JSON), fallback to the `/data/options.json` file, and extract each option using jq +# `bashio::config` try to load the given config key from the supervisor, otherwise it fallbacks to the value of the second parameter +json_config=$(bashio::addon.config) +if [[ "${json_config}" = "{}" ]]; then + json_config_file="/data/options.json" + + bashio::log.info "Loading configuration from $json_config_file" + json_config=$(cat $json_config_file) +fi -certfile="/ssl/$(bashio::config 'certfile')" -keyfile="/ssl/$(bashio::config 'keyfile')" +bashio::log.info "Configuring certificate..." +certfile="/ssl/$(bashio::config 'certfile' "$(bashio::jq "${json_config}" .certfile)")" +keyfile="/ssl/$(bashio::config 'keyfile' "$(bashio::jq "${json_config}" .keyfile)")" readonly certfile keyfile readonly target_certfile="/etc/asterisk/keys/fullchain.pem" @@ -21,7 +31,7 @@ readonly target_keyfile="/etc/asterisk/keys/privkey.pem" mkdir -p /etc/asterisk/keys -if bashio::var.true "$(bashio::config 'generate_ssl_cert')"; then +if bashio::var.true "$(bashio::config 'generate_ssl_cert' "$(bashio::jq "${json_config}" .generate_ssl_cert)")"; then bashio::log.info "Generating a self-signed certificate..." openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 \ @@ -52,13 +62,13 @@ bashio::log.info "Configuring Asterisk..." # Files that can't be changed by user go to /config/asterisk to prevent being overwritten. bashio::var.json \ - password "$(bashio::config 'ami_password')" | + password "$(bashio::config 'ami_password' "$(bashio::jq "${json_config}" .ami_password)")" | tempio \ -template /usr/share/tempio/manager.conf.gtpl \ -out /config/asterisk/manager.conf bashio::var.json \ - log_level "$(bashio::config 'log_level')" | + log_level "$(bashio::config 'log_level' "$(bashio::jq "${json_config}" .log_level)")" | tempio \ -template /usr/share/tempio/logger.conf.gtpl \ -out /config/asterisk/logger.conf @@ -70,19 +80,47 @@ bashio::var.json \ -template /usr/share/tempio/http.conf.gtpl \ -out /config/asterisk/http.conf -persons="$(curl -s -X GET \ - -H "Authorization: Bearer ${SUPERVISOR_TOKEN}" \ - -H "Content-Type: application/json" \ - http://supervisor/core/api/states | - jq -c '[.[] | select(.entity_id | contains("person.")).attributes.id]')" -auto_add=$(bashio::config 'auto_add') -auto_add_secret=$(bashio::config 'auto_add_secret') -video_support=$(bashio::config 'video_support') +# Retrieve the list of persons from the HA API +function get_persons() { + + # Load the base url for Home Assistant as an env variable. + # If not defined (we are running as an add-on), fallback to the supervisor internal proxy URL + HOME_ASSISTANT_URL=${HOME_ASSISTANT_URL:-"http://supervisor/core"} + + # Authentication to Home Assistant API: try to use SUPERVISOR_TOKEN if defined (we are running as an add-on), + # otherwise fallback to HOME_ASSISTANT_TOKEN (supplied manually by the user) + if bashio::var.defined SUPERVISOR_TOKEN; then + HOME_ASSISTANT_TOKEN=${SUPERVISOR_TOKEN} + elif ! bashio::var.defined HOME_ASSISTANT_TOKEN; then + bashio::exit.nok "Please define env variable HOME_ASSISTANT_TOKEN with a long-lived HA access-token" + fi + + persons="$(curl -s -X GET \ + -H "Authorization: Bearer ${HOME_ASSISTANT_TOKEN}" \ + -H "Content-Type: application/json" \ + "${HOME_ASSISTANT_URL}/api/states" | + jq -c '[.[] | select(.entity_id | contains("person.")).attributes.id]')" + + echo "$persons" +} + +auto_add=$(bashio::config 'auto_add' "$(bashio::jq "${json_config}" .auto_add)") +auto_add_secret=$(bashio::config 'auto_add_secret' "$(bashio::jq "${json_config}" .auto_add_secret)") +video_support=$(bashio::config 'video_support' "$(bashio::jq "${json_config}" .video_support)") if bashio::var.true "${auto_add}" && bashio::var.is_empty "${auto_add_secret}"; then bashio::exit.nok "'auto_add_secret' must be set when 'auto_add' is enabled" fi +# If `auto_add` is enabled, retrieve the list of persons using HA API +if bashio::var.true "${auto_add}"; then + bashio::log.debug "Retrieving the list of persons from HA" + persons=$(get_persons) +else + # Define an empty array, so the subsequent template won't complain + persons=[] +fi + bashio::var.json \ auto_add "^${auto_add}" \ auto_add_secret "${auto_add_secret}" \ diff --git a/asterisk/rootfs/etc/cont-init.d/asterisk_mbox.sh b/asterisk/rootfs/etc/cont-init.d/asterisk_mbox.sh index 29c4ec2..ea8e212 100755 --- a/asterisk/rootfs/etc/cont-init.d/asterisk_mbox.sh +++ b/asterisk/rootfs/etc/cont-init.d/asterisk_mbox.sh @@ -5,11 +5,20 @@ # shellcheck shell=bash +# See comments in `asterish.sh` for reference +json_config=$(bashio::addon.config) +if [[ "${json_config}" = "{}" ]]; then + json_config_file="/data/options.json" + + bashio::log.info "Loading configuration from $json_config_file" + json_config=$(cat $json_config_file) +fi + bashio::var.json \ - port "$(bashio::config 'mailbox_port')" \ - password "$(bashio::config 'mailbox_password')" \ - extension "$(bashio::config 'mailbox_extension')" \ - api_key "$(bashio::config 'mailbox_google_api_key')" | + port "$(bashio::config 'mailbox_port' "$(bashio::jq "${json_config}" .mailbox_port)")" \ + password "$(bashio::config 'mailbox_password' "$(bashio::jq "${json_config}" .mailbox_password)")" \ + extension "$(bashio::config 'mailbox_extension' "$(bashio::jq "${json_config}" .mailbox_extension)")" \ + api_key "$(bashio::config 'mailbox_google_api_key' "$(bashio::jq "${json_config}" .mailbox_google_api_key)")" | tempio \ -template /usr/share/tempio/asterisk_mbox.ini.gtpl \ - -out /config/asterisk/asterisk_mbox.ini \ No newline at end of file + -out /config/asterisk/asterisk_mbox.ini From ed25e3b491600ca61027b7c4dab6732aecdf77ff Mon Sep 17 00:00:00 2001 From: Carlo Mion Date: Thu, 16 Mar 2023 14:19:09 +0100 Subject: [PATCH 02/12] fix(tasks.json): update task command to use `sudo` to corectly startup the supervisor --- .vscode/tasks.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 18b0254..d30d452 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -4,7 +4,7 @@ { "label": "Start Home Assistant", "type": "shell", - "command": "bash supervisor_run", + "command": "sudo chmod a+x /usr/bin/supervisor* && sudo -E supervisor_run", "group": { "kind": "test", "isDefault": true From 1c1b75bd10a76143e974d6f1c5051ba088aa660c Mon Sep 17 00:00:00 2001 From: Carlo Mion Date: Thu, 16 Mar 2023 14:51:57 +0100 Subject: [PATCH 03/12] feat(docker-compose.yml): add docker-compose file to help in local development Add example `config.json` file to setup required configuration options. --- asterisk/.gitignore | 2 ++ asterisk/config.json.example | 12 ++++++++++++ docker-compose.yml | 38 ++++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 asterisk/.gitignore create mode 100644 asterisk/config.json.example create mode 100644 docker-compose.yml diff --git a/asterisk/.gitignore b/asterisk/.gitignore new file mode 100644 index 0000000..79ad9ee --- /dev/null +++ b/asterisk/.gitignore @@ -0,0 +1,2 @@ +# Config file used for locally running the container +config.json \ No newline at end of file diff --git a/asterisk/config.json.example b/asterisk/config.json.example new file mode 100644 index 0000000..23687a3 --- /dev/null +++ b/asterisk/config.json.example @@ -0,0 +1,12 @@ +{ + "video_support": true, + "auto_add": false, + "generate_ssl_cert": true, + "certfile": "fullchain.pem", + "keyfile": "privkey.pem", + "mailbox": false, + "mailbox_port": 12345, + "mailbox_extension": "100", + "log_level": "notice", + "ami_password": "admin" +} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..9eaaa05 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,38 @@ +# For locally developing the add-on as a standalone Docker container +version: '3.8' + +services: + asterisk: + image: ghcr.io/tech7fox/amd64-addon-asterisk + build: + context: ./asterisk + network: host + tty: true + entrypoint: /init + init: false + environment: + # To connect to the HA API + HOME_ASSISTANT_URL: http://home-assistant:8123 + HOME_ASSISTANT_TOKEN: + volumes: + # Mount configuration read by the addon + - ./asterisk/config.json:/data/options.json:ro + + # To avoid having to rebuild the whole image, mount the init files inside it + # - ./asterisk/rootfs/etc/cont-init.d/asterisk.sh:/etc/cont-init.d/asterisk.sh:ro + # - ./asterisk/rootfs/etc/cont-init.d/asterisk_mbox.sh:/etc/cont-init.d/asterisk_mbox.sh:ro + + # To test the add-on against an HA instance + home-assistant: + container_name: home-assistant + image: homeassistant/home-assistant:2023.2 + volumes: + - /etc/localtime:/etc/localtime:ro # To use host local time + - config:/config # To keep HA configuration between container creations & destructions + mem_limit: 600m + stop_grace_period: 5m + ports: + - 8123:8123 + +volumes: + config: {} \ No newline at end of file From cb3dd221cae1fea670879988996431e8b5fcf223 Mon Sep 17 00:00:00 2001 From: Carlo Mion Date: Thu, 16 Mar 2023 15:35:48 +0100 Subject: [PATCH 04/12] refactor(config.sh): move configuration parsing in utility function --- asterisk/rootfs/etc/cont-init.d/asterisk.sh | 31 +++++++------------ .../rootfs/etc/cont-init.d/asterisk_mbox.sh | 19 +++++------- .../rootfs/etc/services.d/asterisk_mbox/run | 6 +++- asterisk/rootfs/etc/services.d/discovery/run | 6 +++- asterisk/rootfs/usr/lib/config.sh | 22 +++++++++++++ 5 files changed, 51 insertions(+), 33 deletions(-) create mode 100644 asterisk/rootfs/usr/lib/config.sh diff --git a/asterisk/rootfs/etc/cont-init.d/asterisk.sh b/asterisk/rootfs/etc/cont-init.d/asterisk.sh index 804cbfe..1de2979 100755 --- a/asterisk/rootfs/etc/cont-init.d/asterisk.sh +++ b/asterisk/rootfs/etc/cont-init.d/asterisk.sh @@ -5,25 +5,18 @@ # shellcheck shell=bash +# Load helper function +# shellcheck source=/dev/null +source /usr/lib/config.sh + if ! bashio::fs.directory_exists '/config/asterisk'; then mkdir -p /config/asterisk || bashio::exit.nok 'Failed to create initial asterisk config folder' fi -# Try to read the configuration from the supervisor API. -# If the supervisor is not available (the function returns an empty JSON), fallback to the `/data/options.json` file, and extract each option using jq -# `bashio::config` try to load the given config key from the supervisor, otherwise it fallbacks to the value of the second parameter -json_config=$(bashio::addon.config) -if [[ "${json_config}" = "{}" ]]; then - json_config_file="/data/options.json" - - bashio::log.info "Loading configuration from $json_config_file" - json_config=$(cat $json_config_file) -fi - bashio::log.info "Configuring certificate..." -certfile="/ssl/$(bashio::config 'certfile' "$(bashio::jq "${json_config}" .certfile)")" -keyfile="/ssl/$(bashio::config 'keyfile' "$(bashio::jq "${json_config}" .keyfile)")" +certfile="/ssl/$(config 'certfile')" +keyfile="/ssl/$(config 'keyfile')" readonly certfile keyfile readonly target_certfile="/etc/asterisk/keys/fullchain.pem" @@ -31,7 +24,7 @@ readonly target_keyfile="/etc/asterisk/keys/privkey.pem" mkdir -p /etc/asterisk/keys -if bashio::var.true "$(bashio::config 'generate_ssl_cert' "$(bashio::jq "${json_config}" .generate_ssl_cert)")"; then +if bashio::var.true "$(config 'generate_ssl_cert')"; then bashio::log.info "Generating a self-signed certificate..." openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 \ @@ -62,13 +55,13 @@ bashio::log.info "Configuring Asterisk..." # Files that can't be changed by user go to /config/asterisk to prevent being overwritten. bashio::var.json \ - password "$(bashio::config 'ami_password' "$(bashio::jq "${json_config}" .ami_password)")" | + password "$(config 'ami_password')" | tempio \ -template /usr/share/tempio/manager.conf.gtpl \ -out /config/asterisk/manager.conf bashio::var.json \ - log_level "$(bashio::config 'log_level' "$(bashio::jq "${json_config}" .log_level)")" | + log_level "$(config 'log_level')" | tempio \ -template /usr/share/tempio/logger.conf.gtpl \ -out /config/asterisk/logger.conf @@ -105,9 +98,9 @@ function get_persons() { echo "$persons" } -auto_add=$(bashio::config 'auto_add' "$(bashio::jq "${json_config}" .auto_add)") -auto_add_secret=$(bashio::config 'auto_add_secret' "$(bashio::jq "${json_config}" .auto_add_secret)") -video_support=$(bashio::config 'video_support' "$(bashio::jq "${json_config}" .video_support)") +auto_add=$(config 'auto_add') +auto_add_secret=$(config 'auto_add_secret') +video_support=$(config 'video_support') if bashio::var.true "${auto_add}" && bashio::var.is_empty "${auto_add_secret}"; then bashio::exit.nok "'auto_add_secret' must be set when 'auto_add' is enabled" fi diff --git a/asterisk/rootfs/etc/cont-init.d/asterisk_mbox.sh b/asterisk/rootfs/etc/cont-init.d/asterisk_mbox.sh index ea8e212..26182fc 100755 --- a/asterisk/rootfs/etc/cont-init.d/asterisk_mbox.sh +++ b/asterisk/rootfs/etc/cont-init.d/asterisk_mbox.sh @@ -5,20 +5,15 @@ # shellcheck shell=bash -# See comments in `asterish.sh` for reference -json_config=$(bashio::addon.config) -if [[ "${json_config}" = "{}" ]]; then - json_config_file="/data/options.json" - - bashio::log.info "Loading configuration from $json_config_file" - json_config=$(cat $json_config_file) -fi +# Load helper function +# shellcheck source=/dev/null +source /usr/lib/config.sh bashio::var.json \ - port "$(bashio::config 'mailbox_port' "$(bashio::jq "${json_config}" .mailbox_port)")" \ - password "$(bashio::config 'mailbox_password' "$(bashio::jq "${json_config}" .mailbox_password)")" \ - extension "$(bashio::config 'mailbox_extension' "$(bashio::jq "${json_config}" .mailbox_extension)")" \ - api_key "$(bashio::config 'mailbox_google_api_key' "$(bashio::jq "${json_config}" .mailbox_google_api_key)")" | + port "$(config 'mailbox_port')" \ + password "$(config 'mailbox_password')" \ + extension "$(config 'mailbox_extension')" \ + api_key "$(config 'mailbox_google_api_key')" | tempio \ -template /usr/share/tempio/asterisk_mbox.ini.gtpl \ -out /config/asterisk/asterisk_mbox.ini diff --git a/asterisk/rootfs/etc/services.d/asterisk_mbox/run b/asterisk/rootfs/etc/services.d/asterisk_mbox/run index a8dd292..e54927b 100755 --- a/asterisk/rootfs/etc/services.d/asterisk_mbox/run +++ b/asterisk/rootfs/etc/services.d/asterisk_mbox/run @@ -6,7 +6,11 @@ # shellcheck shell=bash -if bashio::var.false "$(bashio::config 'mailbox')"; then +# Load helper function +# shellcheck source=/dev/null +source /usr/lib/config.sh + +if bashio::var.false "$(config 'mailbox')"; then # Tell S6-Overlay not to restart this service s6-svc -O . exit 0 diff --git a/asterisk/rootfs/etc/services.d/discovery/run b/asterisk/rootfs/etc/services.d/discovery/run index 9721ad3..4ecd0a6 100755 --- a/asterisk/rootfs/etc/services.d/discovery/run +++ b/asterisk/rootfs/etc/services.d/discovery/run @@ -6,6 +6,10 @@ # shellcheck shell=bash +# Load helper function +# shellcheck source=/dev/null +source /usr/lib/config.sh + # Wait for Asterisk to become available before continuing bashio::net.wait_for 8088 @@ -14,7 +18,7 @@ discovery_config=$(bashio::var.json \ host "127.0.0.1" \ port "5038" \ username "admin" \ - password "$(bashio::config 'ami_password')" + password "$(config 'ami_password')" ) readonly discovery_config diff --git a/asterisk/rootfs/usr/lib/config.sh b/asterisk/rootfs/usr/lib/config.sh new file mode 100644 index 0000000..9b5f824 --- /dev/null +++ b/asterisk/rootfs/usr/lib/config.sh @@ -0,0 +1,22 @@ +#!/usr/bin/env bash + + +readonly JSON_CONFIG_FILE="/data/options.json" + +# Load configuration values using either `bashio::config` (if supervisor is available) or from a JSON file +function config() { + local key=${1} + + # Try to read the configuration from the supervisor API. + # If the supervisor is not available (the function returns an empty JSON), fallback to the `/data/options.json` file, and extract each option using jq + json_config=$(bashio::addon.config) + + if [[ "${json_config}" = "{}" ]]; then + + bashio::log.info "Loading configuration from $JSON_CONFIG_FILE" + json_config=$(cat $JSON_CONFIG_FILE) + fi + + # `bashio::config` try to load the given config key from the supervisor, otherwise it fallbacks to the value of the second parameter + bashio::config "${key}" "$(bashio::jq "${json_config}" ."${key}")" +} \ No newline at end of file From 150b8d2d56a2295beb094b2f829eedcfec2ea9d0 Mon Sep 17 00:00:00 2001 From: Felipe Santos Date: Thu, 23 Mar 2023 00:41:58 -0300 Subject: [PATCH 05/12] Fix all issues, re-implement, etc --- .gitignore | 5 + .vscode/settings.json | 5 +- .vscode/tasks.json | 2 +- asterisk/.gitignore | 2 - asterisk/CHANGELOG.md | 28 ++++ asterisk/DOCS.md | 32 +++-- asterisk/Dockerfile | 6 +- asterisk/config.json.example | 12 -- asterisk/config.yaml | 8 +- asterisk/rootfs/entrypoint.sh | 13 ++ .../etc/asterisk-addon/default_config.json | 16 +++ asterisk/rootfs/etc/asterisk-addon/noop.sh | 3 + asterisk/rootfs/etc/cont-init.d/asterisk.sh | 120 +++++++++++------- .../rootfs/etc/services.d/asterisk/finish | 4 +- asterisk/rootfs/etc/services.d/asterisk/run | 4 +- .../etc/services.d/asterisk_mbox/finish | 10 +- .../rootfs/etc/services.d/asterisk_mbox/run | 9 +- asterisk/rootfs/etc/services.d/discovery/run | 35 ----- asterisk/rootfs/stdin.sh | 8 ++ asterisk/rootfs/usr/lib/config.sh | 22 ---- config/.gitkeep | 0 docker-compose.yaml | 13 ++ docker-compose.yml | 38 ------ media/.gitkeep | 0 24 files changed, 201 insertions(+), 194 deletions(-) create mode 100644 .gitignore delete mode 100644 asterisk/.gitignore delete mode 100644 asterisk/config.json.example create mode 100755 asterisk/rootfs/entrypoint.sh create mode 100644 asterisk/rootfs/etc/asterisk-addon/default_config.json create mode 100755 asterisk/rootfs/etc/asterisk-addon/noop.sh delete mode 100755 asterisk/rootfs/etc/services.d/discovery/run delete mode 100644 asterisk/rootfs/usr/lib/config.sh create mode 100644 config/.gitkeep create mode 100644 docker-compose.yaml delete mode 100644 docker-compose.yml create mode 100644 media/.gitkeep diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..241fd19 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +/config/* +!/config/.gitkeep + +/media/* +!/media/.gitkeep diff --git a/.vscode/settings.json b/.vscode/settings.json index c658501..ad96bed 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -19,5 +19,8 @@ }, "docker.languageserver.formatter.ignoreMultilineInstructions": true, "files.trimTrailingWhitespace": true, - "files.insertFinalNewline": true + "files.insertFinalNewline": true, + "files.associations": { + "*.json.example": "json" + } } diff --git a/.vscode/tasks.json b/.vscode/tasks.json index d30d452..bccf30a 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -4,7 +4,7 @@ { "label": "Start Home Assistant", "type": "shell", - "command": "sudo chmod a+x /usr/bin/supervisor* && sudo -E supervisor_run", + "command": "sudo -E bash supervisor_run", "group": { "kind": "test", "isDefault": true diff --git a/asterisk/.gitignore b/asterisk/.gitignore deleted file mode 100644 index 79ad9ee..0000000 --- a/asterisk/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -# Config file used for locally running the container -config.json \ No newline at end of file diff --git a/asterisk/CHANGELOG.md b/asterisk/CHANGELOG.md index 52ba0f4..6622fe0 100644 --- a/asterisk/CHANGELOG.md +++ b/asterisk/CHANGELOG.md @@ -2,6 +2,34 @@ # Changelog +## 4.0.0 + +### Breaking Changes + +Some default options for the add-on configuration have been switched: + +- `generate_ssl_cert` is now enabled by default. +- `video_support` is now disabled by default. It barely worked anyway. + +Make sure to check the add-on configuration page after updating the add-on to ensure your configuration is still correct. + +### New Features + +Now the add-on can be run as a standalone docker container. + +- An example `docker-compose.yml` file is available [here](../docker-compose.yaml). +- Make sure to mount a `config` folder to `/config` and a `media` folder to `/media` to ensure the add-on can access your configuration and media files. +- To configure the add-on options you can use the `/config/config.json` file. The default options can be seen [here](./rootfs/usr/share/asterisk/config.json). +- If you enable `auto_add` to automatically create extensions for every Person in your Home Assistant, make sure to also set: + - The `HA_TOKEN` environment variable with your Home Assistant long-lived access token + - The `HA_URL`, unless resolves to your Home Assistant instance + +Also, you can now use absolute paths in the `certfile` and `keyfile` options. + +### Cleanups + +The add-on no longer sends discovery information for the Asterisk integration in Home Assistant. This never worked anyway, and if in the future it does, we can restore it. + ## 3.2.0 ### New Features diff --git a/asterisk/DOCS.md b/asterisk/DOCS.md index 7fbc90b..43215fe 100644 --- a/asterisk/DOCS.md +++ b/asterisk/DOCS.md @@ -40,17 +40,19 @@ We expose some configuration options to simplify the setup of the Asterisk serve Set's the password for the Asterisk Manager Interface, to connect to the [Asterisk integration](https://github.com/TECH7Fox/Asterisk-integration). -### Option: `video_support` - -Enables video support for the auto generated extensions. - ### Option: `auto_add` Creates a extension for every [person](https://www.home-assistant.io/integrations/person/) registered in Home Assistant. They will have their number and username auto-generated starting from 100, with the `callerid` set to the person's name. +**This is enabled by default for add-on users but disabled by default for container users.** + ### Option: `auto_add_secret` -The secret for the auto generated extensions. +The secret for the auto generated extensions, when `auto_add` is enabled. + +### Option: `video_support` + +Enables video support for the auto generated extensions, when `auto_add` is enabled. ### Option: `additional_sounds` @@ -66,15 +68,15 @@ Enables/disables the generation of a self-signed certificate for use with the SS ### Option: `certfile` -The certificate file to use for SSL in your `/ssl/` folder, when `generate_ssl_cert` is disabled. +The certificate file to use for SSL in your `/ssl/` folder, when `generate_ssl_cert` is disabled. If an absolute path is provided, it will be used as-is. ### Option: `keyfile` -The key file to use for SSL in your `/ssl/` folder, when `generate_ssl_cert` is disabled. +The key file to use for SSL in your `/ssl/` folder, when `generate_ssl_cert` is disabled. If an absolute path is provided, it will be used as-is. -### Option: `mailbox_server` +### Option: `mailbox` -Enables the mailbox server to send voicemails to the Asterisk mailbox integration. +Enables the mailbox server to send voicemails to the Asterisk Mailbox integration. ### Option: `mailbox_port` @@ -88,9 +90,9 @@ The password for the mailbox server. Which extension to get the voicemails from. -### Option: `api_key` +### Option: `mailbox_google_api_key` -The API Key for speech-to-text. +The API Key for the speech-to-text used by Asterisk Mailbox. You can get a key [here](https://cloud.google.com/speech-to-text). Google says it's free, but requires a billing account. ### Option: `log_level` @@ -108,16 +110,18 @@ service: hassio.addon_stdin input: dialplan reload ``` +**This is only possible when using as an add-on.** + ## Configuring the [Asterisk integration](https://github.com/TECH7Fox/Asterisk-integration) -- **_Host_**: `localhost` +- **_Host_**: `localhost` (when running as an add-on) - **_Port_**: `5038` - **_Username_**: `admin` -- **_Password_**: whatever you set in the AMI Password configuration +- **_Password_**: whatever you set in the `ami_password` configuration ## Configuring the [SIP.js card](https://github.com/TECH7Fox/HA-SIP) -- **_Host_**: `localhost` +- **_Host_**: `localhost` (when running as an add-on) - **_Port_**: `8089` - **_Video_**: `false` _Video is not working at the moment, this will be fixed soon. For now you could use the camera entity instead._ diff --git a/asterisk/Dockerfile b/asterisk/Dockerfile index 9e663b0..a4029ac 100644 --- a/asterisk/Dockerfile +++ b/asterisk/Dockerfile @@ -7,11 +7,6 @@ FROM $BUILD_FROM AS base SHELL [ "/bin/bash", "-euxo", "pipefail", "-c" ] -# Add additional Debian APT mirror, since the default `deb.debian.org` randomly returns `502 connection timed out` -RUN echo $'deb http://ftp.it.debian.org/debian/ bullseye main \n\ -deb http://debian.mirror.garr.it/debian-security/ bullseye-security main \n\ -deb http://ftp.it.debian.org/debian/ bullseye-updates main' > /etc/apt/sources.list.d/mirror.list - # https://pypi.org/project/asterisk_mbox_server/#history ARG ASTERISK_MBOX_SERVER_VERSION="0.5.3" RUN export DEBIAN_FRONTEND=noninteractive; \ @@ -294,4 +289,5 @@ ENV S6_SERVICES_READYTIME=50 # Without this, the STDIN script never gets executed ENV S6_CMD_WAIT_FOR_SERVICES=0 +ENTRYPOINT [ "/entrypoint.sh" ] CMD [ "/stdin.sh" ] diff --git a/asterisk/config.json.example b/asterisk/config.json.example deleted file mode 100644 index 23687a3..0000000 --- a/asterisk/config.json.example +++ /dev/null @@ -1,12 +0,0 @@ -{ - "video_support": true, - "auto_add": false, - "generate_ssl_cert": true, - "certfile": "fullchain.pem", - "keyfile": "privkey.pem", - "mailbox": false, - "mailbox_port": 12345, - "mailbox_extension": "100", - "log_level": "notice", - "ami_password": "admin" -} diff --git a/asterisk/config.yaml b/asterisk/config.yaml index 0f53400..85fe2b2 100644 --- a/asterisk/config.yaml +++ b/asterisk/config.yaml @@ -1,5 +1,5 @@ name: Asterisk -version: 3.2.0 +version: 4.0.0 slug: asterisk description: PBX server for SIP devices like doorbells and phones url: https://github.com/TECH7Fox/asterisk-hass-addons @@ -17,10 +17,10 @@ map: - ssl options: ami_password: null - video_support: true auto_add: true auto_add_secret: "" - generate_ssl_cert: false + video_support: false + generate_ssl_cert: true certfile: fullchain.pem keyfile: privkey.pem additional_sounds: [] @@ -32,9 +32,9 @@ options: log_level: info schema: ami_password: password - video_support: bool auto_add: bool auto_add_secret: password + video_support: bool additional_sounds: - str generate_ssl_cert: bool diff --git a/asterisk/rootfs/entrypoint.sh b/asterisk/rootfs/entrypoint.sh new file mode 100755 index 0000000..d34b0a0 --- /dev/null +++ b/asterisk/rootfs/entrypoint.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +function is_addon() { + [[ -n "${SUPERVISOR_TOKEN:-}" ]] +} + +# Stub scripts that only works as an add-on +if ! is_addon; then + cp -f /etc/asterisk-addon/noop.sh /package/admin/s6-overlay/etc/s6-rc/scripts/base-addon-log-level + cp -f /etc/asterisk-addon/noop.sh /package/admin/s6-overlay/etc/s6-rc/scripts/base-addon-banner +fi + +exec /init "${@}" diff --git a/asterisk/rootfs/etc/asterisk-addon/default_config.json b/asterisk/rootfs/etc/asterisk-addon/default_config.json new file mode 100644 index 0000000..e678239 --- /dev/null +++ b/asterisk/rootfs/etc/asterisk-addon/default_config.json @@ -0,0 +1,16 @@ +{ + "ami_password": null, + "video_support": false, + "auto_add": false, + "auto_add_secret": "", + "generate_ssl_cert": true, + "certfile": "/config/ssl/fullchain.pem", + "keyfile": "/config/ssl/privkey.pem", + "additional_sounds": [], + "mailbox": false, + "mailbox_port": 12345, + "mailbox_password": "", + "mailbox_extension": "100", + "mailbox_google_api_key": "", + "log_level": "info" +} diff --git a/asterisk/rootfs/etc/asterisk-addon/noop.sh b/asterisk/rootfs/etc/asterisk-addon/noop.sh new file mode 100755 index 0000000..e41f412 --- /dev/null +++ b/asterisk/rootfs/etc/asterisk-addon/noop.sh @@ -0,0 +1,3 @@ +#!/bin/bash + +exec true diff --git a/asterisk/rootfs/etc/cont-init.d/asterisk.sh b/asterisk/rootfs/etc/cont-init.d/asterisk.sh index d5f692f..dd28dcf 100755 --- a/asterisk/rootfs/etc/cont-init.d/asterisk.sh +++ b/asterisk/rootfs/etc/cont-init.d/asterisk.sh @@ -5,6 +5,33 @@ # shellcheck shell=bash +function is_addon() { + [[ -n "${SUPERVISOR_TOKEN:-}" ]] +} + +if is_addon; then + readonly ha_url="http://supervisor/core" +else + readonly default_ha_url="http://homeassistant.local:8123" + readonly ha_url="${HA_URL:-"${default_ha_url}"}" + + readonly addon_config_path="/config/config.json" + readonly default_addon_config_path="/etc/asterisk-addon/default_config.json" + if [[ -f "${addon_config_path}" ]]; then + addon_config=$( + jq --slurp 'reduce .[] as $item ({}; . * $item)' "${default_addon_config_path}" "${addon_config_path}" + ) + else + addon_config=$(cat "${default_addon_config_path}") + fi + + # Overrides calling the Supervisor API on bashio::config calls + function bashio::addon.config() { + echo "${addon_config}" + } +fi +readonly ha_token="${HA_TOKEN:-"${SUPERVISOR_TOKEN:-}"}" + readonly etc_asterisk="/etc/asterisk" readonly config_dir="/config/asterisk" readonly default_config_dir="${config_dir}/default" @@ -18,8 +45,19 @@ if ! mkdir -p "${default_config_dir}" "${custom_config_dir}"; then fi bashio::log.info "Configuring certificate..." -certfile="/ssl/$(config 'certfile')" -keyfile="/ssl/$(config 'keyfile')" +certfile_config=$(bashio::config 'certfile') +keyfile_config=$(bashio::config 'keyfile') +if [[ "${certfile_config}" == /* ]]; then + certfile="${certfile_config}" +else + certfile="/ssl/${certfile_config}" +fi +if [[ "${keyfile_config}" == /* ]]; then + keyfile="${keyfile_config}" +else + keyfile="/ssl/${keyfile_config}" +fi +unset certfile_config keyfile_config readonly certfile keyfile readonly keys_dir="${etc_asterisk}/keys" @@ -28,7 +66,7 @@ readonly target_keyfile="${keys_dir}/privkey.pem" mkdir -p "${keys_dir}" -if bashio::var.true "$(config 'generate_ssl_cert')"; then +if bashio::var.true "$(bashio::config 'generate_ssl_cert')"; then bashio::log.info "Generating a self-signed certificate..." openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 \ @@ -54,14 +92,18 @@ chmod 600 "${keys_dir}"/*.pem bashio::log.info "Generating Asterisk config files from add-on configuration..." +if bashio::config.is_empty 'ami_password'; then + bashio::exit.nok "'ami_password' must be set" +fi + bashio::var.json \ - password "$(config 'ami_password')" | + password "$(bashio::config 'ami_password')" | tempio \ -template "${tempio_dir}/manager.conf.gtpl" \ -out "${etc_asterisk}/manager.conf" bashio::var.json \ - log_level "$(config 'log_level')" | + log_level "$(bashio::config 'log_level')" | tempio \ -template "${tempio_dir}/logger.conf.gtpl" \ -out "${etc_asterisk}/logger.conf" @@ -73,49 +115,31 @@ bashio::var.json \ -template "${tempio_dir}/http.conf.gtpl" \ -out "${etc_asterisk}/http.conf" -persons="$( - curl -fsSL -X GET \ - -H "Authorization: Bearer ${SUPERVISOR_TOKEN}" \ - -H "Content-Type: application/json" \ - http://supervisor/core/api/states | - jq -c '[.[] | select(.entity_id | contains("person.")).attributes.id]' -)" - -# Retrieve the list of persons from the HA API -function get_persons() { - - # Load the base url for Home Assistant as an env variable. - # If not defined (we are running as an add-on), fallback to the supervisor internal proxy URL - HOME_ASSISTANT_URL=${HOME_ASSISTANT_URL:-"http://supervisor/core"} - - # Authentication to Home Assistant API: try to use SUPERVISOR_TOKEN if defined (we are running as an add-on), - # otherwise fallback to HOME_ASSISTANT_TOKEN (supplied manually by the user) - if bashio::var.defined SUPERVISOR_TOKEN; then - HOME_ASSISTANT_TOKEN=${SUPERVISOR_TOKEN} - elif ! bashio::var.defined HOME_ASSISTANT_TOKEN; then - bashio::exit.nok "Please define env variable HOME_ASSISTANT_TOKEN with a long-lived HA access-token" - fi - - persons="$(curl -s -X GET \ - -H "Authorization: Bearer ${HOME_ASSISTANT_TOKEN}" \ - -H "Content-Type: application/json" \ - "${HOME_ASSISTANT_URL}/api/states" | - jq -c '[.[] | select(.entity_id | contains("person.")).attributes.id]')" - - echo "$persons" -} - -auto_add=$(config 'auto_add') -auto_add_secret=$(config 'auto_add_secret') -video_support=$(config 'video_support') -if bashio::var.true "${auto_add}" && bashio::var.is_empty "${auto_add_secret}"; then - bashio::exit.nok "'auto_add_secret' must be set when 'auto_add' is enabled" -fi +auto_add=$(bashio::config 'auto_add') +auto_add_secret=$(bashio::config 'auto_add_secret') +video_support=$(bashio::config 'video_support') -# If `auto_add` is enabled, retrieve the list of persons using HA API +# If `auto_add` is enabled, retrieve the list of persons using the Home Assistant API if bashio::var.true "${auto_add}"; then - bashio::log.debug "Retrieving the list of persons from HA" - persons=$(get_persons) + if bashio::config.is_empty "${auto_add_secret}"; then + bashio::exit.nok "'auto_add_secret' must be set when 'auto_add' is enabled" + fi + + bashio::log.info "Retrieving the list of persons from Home Assistant" + if ! is_addon && bashio::var.is_empty "${ha_token}"; then + message="Please define the HA_TOKEN env variable with a long-lived Home Assistant access token so the container can get the list of persons from Home Assistant." + if [[ -z "${HA_URL:-}" ]]; then + message="${message} Optionally, you can also define the HA_URL env variable to point to your Home Assistant URL if it differs from ${default_ha_url}." + fi + bashio::exit.nok "${message}" + fi + persons=$( + curl -fsSL -X GET \ + -H "Authorization: Bearer ${ha_token}" \ + -H "Content-Type: application/json" \ + "${ha_url}/api/states" | + jq -c '[.[] | select(.entity_id | contains("person.")).attributes.id]' + ) else # Define an empty array, so the subsequent template won't complain persons=[] @@ -148,6 +172,10 @@ bashio::var.json \ -template "${tempio_dir}/asterisk_mbox.ini.gtpl" \ -out "${etc_asterisk}/asterisk_mbox.ini" +if bashio::var.false "$(bashio::config 'mailbox')"; then + touch /tmp/disable-asterisk-mailbox +fi + # Save default configs bashio::log.info "Saving default configs to ${default_config_dir}..." if ! rsync --archive --delete "${etc_asterisk}/" "${default_config_dir}/"; then diff --git a/asterisk/rootfs/etc/services.d/asterisk/finish b/asterisk/rootfs/etc/services.d/asterisk/finish index c96d75a..e4e183d 100755 --- a/asterisk/rootfs/etc/services.d/asterisk/finish +++ b/asterisk/rootfs/etc/services.d/asterisk/finish @@ -6,8 +6,8 @@ # shellcheck shell=bash if [[ "${1}" -ne 0 ]] && [[ "${1}" -ne 256 ]]; then - bashio::log.warning "asterisk crashed, halting add-on" + bashio::log.warning "Asterisk crashed, halting add-on..." /run/s6/basedir/bin/halt fi -bashio::log.info "asterisk stopped, restarting..." +bashio::log.info "Asterisk stopped, restarting..." diff --git a/asterisk/rootfs/etc/services.d/asterisk/run b/asterisk/rootfs/etc/services.d/asterisk/run index 5634832..59d5a9d 100755 --- a/asterisk/rootfs/etc/services.d/asterisk/run +++ b/asterisk/rootfs/etc/services.d/asterisk/run @@ -1,6 +1,6 @@ #!/usr/bin/with-contenv bashio # ============================================================================== -# Start the asterisk service +# Start the Asterisk service # s6-overlay docs: https://github.com/just-containers/s6-overlay # ============================================================================== @@ -9,4 +9,4 @@ bashio::log.info "Starting Asterisk..." ## Run Asterisk -exec asterisk -T -f \ No newline at end of file +exec asterisk -T -f diff --git a/asterisk/rootfs/etc/services.d/asterisk_mbox/finish b/asterisk/rootfs/etc/services.d/asterisk_mbox/finish index 40c0b44..d8ec50f 100755 --- a/asterisk/rootfs/etc/services.d/asterisk_mbox/finish +++ b/asterisk/rootfs/etc/services.d/asterisk_mbox/finish @@ -1,13 +1,17 @@ #!/usr/bin/with-contenv bashio # ============================================================================== -# Take down the S6 supervision tree when asterisk mailbox fails +# Take down the S6 supervision tree when Asterisk Mailbox fails # ============================================================================== # shellcheck shell=bash +if [[ -f "/tmp/disable-asterisk-mailbox" ]]; then + exit 0 +fi + if [[ "${1}" -ne 0 ]] && [[ "${1}" -ne 256 ]]; then - bashio::log.warning "asterisk mailbox crashed, halting add-on" + bashio::log.warning "Asterisk Mailbox crashed, halting add-on..." /run/s6/basedir/bin/halt fi -bashio::log.info "asterisk mailbox stopped, restarting..." +bashio::log.info "Asterisk Mailbox stopped, restarting..." diff --git a/asterisk/rootfs/etc/services.d/asterisk_mbox/run b/asterisk/rootfs/etc/services.d/asterisk_mbox/run index e54927b..5d4da08 100755 --- a/asterisk/rootfs/etc/services.d/asterisk_mbox/run +++ b/asterisk/rootfs/etc/services.d/asterisk_mbox/run @@ -6,17 +6,12 @@ # shellcheck shell=bash -# Load helper function -# shellcheck source=/dev/null -source /usr/lib/config.sh - -if bashio::var.false "$(config 'mailbox')"; then +if [[ -f "/tmp/disable-asterisk-mailbox" ]]; then # Tell S6-Overlay not to restart this service s6-svc -O . exit 0 fi -bashio::log.info "Starting Asterisk Mailbox" +bashio::log.info "Starting Asterisk Mailbox..." -## Run Asterisk_mbox exec asterisk-mbox-server --cfg /etc/asterisk/asterisk_mbox.ini diff --git a/asterisk/rootfs/etc/services.d/discovery/run b/asterisk/rootfs/etc/services.d/discovery/run deleted file mode 100755 index 4ecd0a6..0000000 --- a/asterisk/rootfs/etc/services.d/discovery/run +++ /dev/null @@ -1,35 +0,0 @@ -#!/usr/bin/with-contenv bashio -# ============================================================================== -# Home Assistant Community Add-on: Asterisk -# Send Discovery information to Home Assistant -# ============================================================================== - -# shellcheck shell=bash - -# Load helper function -# shellcheck source=/dev/null -source /usr/lib/config.sh - -# Wait for Asterisk to become available before continuing -bashio::net.wait_for 8088 - -# Create discovery config payload for Home Assistant -discovery_config=$(bashio::var.json \ - host "127.0.0.1" \ - port "5038" \ - username "admin" \ - password "$(config 'ami_password')" -) -readonly discovery_config - -bashio::log.info "Sending discovery information to Home Assistant..." - -# Send discovery info -if bashio::discovery "asterisk" "${discovery_config}" > /dev/null; then - bashio::log.info "Successfully send discovery information to Home Assistant." -else - bashio::log.error "Discovery message to Home Assistant failed!" -fi - -# Tell S6-Overlay not to restart this service -s6-svc -O . diff --git a/asterisk/rootfs/stdin.sh b/asterisk/rootfs/stdin.sh index af16780..60602d8 100755 --- a/asterisk/rootfs/stdin.sh +++ b/asterisk/rootfs/stdin.sh @@ -1,6 +1,14 @@ #!/usr/bin/with-contenv bashio # shellcheck shell=bash +function is_addon() { + [[ -n "${SUPERVISOR_TOKEN:-}" ]] +} + +if ! is_addon; then + exec sleep infinity +fi + bashio::log.info 'Starting the STDIN service for Home Assistant...' # shellcheck disable=SC2162 diff --git a/asterisk/rootfs/usr/lib/config.sh b/asterisk/rootfs/usr/lib/config.sh deleted file mode 100644 index 9b5f824..0000000 --- a/asterisk/rootfs/usr/lib/config.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/usr/bin/env bash - - -readonly JSON_CONFIG_FILE="/data/options.json" - -# Load configuration values using either `bashio::config` (if supervisor is available) or from a JSON file -function config() { - local key=${1} - - # Try to read the configuration from the supervisor API. - # If the supervisor is not available (the function returns an empty JSON), fallback to the `/data/options.json` file, and extract each option using jq - json_config=$(bashio::addon.config) - - if [[ "${json_config}" = "{}" ]]; then - - bashio::log.info "Loading configuration from $JSON_CONFIG_FILE" - json_config=$(cat $JSON_CONFIG_FILE) - fi - - # `bashio::config` try to load the given config key from the supervisor, otherwise it fallbacks to the value of the second parameter - bashio::config "${key}" "$(bashio::jq "${json_config}" ."${key}")" -} \ No newline at end of file diff --git a/config/.gitkeep b/config/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..b4d71e0 --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,13 @@ +services: + asterisk: + image: ghcr.io/tech7fox/amd64-addon-asterisk:latest + build: + context: ./asterisk + tty: true + network_mode: host + environment: + # Required to get the list of persons from Home Assistant + HA_TOKEN: "" + volumes: + - ./config:/config + - ./media:/media diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index 9eaaa05..0000000 --- a/docker-compose.yml +++ /dev/null @@ -1,38 +0,0 @@ -# For locally developing the add-on as a standalone Docker container -version: '3.8' - -services: - asterisk: - image: ghcr.io/tech7fox/amd64-addon-asterisk - build: - context: ./asterisk - network: host - tty: true - entrypoint: /init - init: false - environment: - # To connect to the HA API - HOME_ASSISTANT_URL: http://home-assistant:8123 - HOME_ASSISTANT_TOKEN: - volumes: - # Mount configuration read by the addon - - ./asterisk/config.json:/data/options.json:ro - - # To avoid having to rebuild the whole image, mount the init files inside it - # - ./asterisk/rootfs/etc/cont-init.d/asterisk.sh:/etc/cont-init.d/asterisk.sh:ro - # - ./asterisk/rootfs/etc/cont-init.d/asterisk_mbox.sh:/etc/cont-init.d/asterisk_mbox.sh:ro - - # To test the add-on against an HA instance - home-assistant: - container_name: home-assistant - image: homeassistant/home-assistant:2023.2 - volumes: - - /etc/localtime:/etc/localtime:ro # To use host local time - - config:/config # To keep HA configuration between container creations & destructions - mem_limit: 600m - stop_grace_period: 5m - ports: - - 8123:8123 - -volumes: - config: {} \ No newline at end of file diff --git a/media/.gitkeep b/media/.gitkeep new file mode 100644 index 0000000..e69de29 From 7e6d3e54a04e73458d1956252b349e1d66524a88 Mon Sep 17 00:00:00 2001 From: Felipe Santos Date: Thu, 23 Mar 2023 00:50:04 -0300 Subject: [PATCH 06/12] Try to simplify image tag --- asterisk/build.yaml | 10 +++++----- asterisk/config.yaml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/asterisk/build.yaml b/asterisk/build.yaml index 2d7b5d4..6174b93 100644 --- a/asterisk/build.yaml +++ b/asterisk/build.yaml @@ -1,9 +1,9 @@ build_from: - aarch64: ghcr.io/hassio-addons/debian-base/aarch64:6.2.3 - amd64: ghcr.io/hassio-addons/debian-base/amd64:6.2.3 - armhf: ghcr.io/hassio-addons/debian-base/armhf:6.2.3 - armv7: ghcr.io/hassio-addons/debian-base/armv7:6.2.3 - i386: ghcr.io/hassio-addons/debian-base/i386:6.2.3 + aarch64: ghcr.io/hassio-addons/debian-base:6.2.3 + amd64: ghcr.io/hassio-addons/debian-base:6.2.3 + armhf: ghcr.io/hassio-addons/debian-base:6.2.3 + armv7: ghcr.io/hassio-addons/debian-base:6.2.3 + i386: ghcr.io/hassio-addons/debian-base:6.2.3 labels: org.opencontainers.image.title: "Home Assistant Add-on: Asterisk" org.opencontainers.image.description: "PBX server for SIP devices like doorbells and phones." diff --git a/asterisk/config.yaml b/asterisk/config.yaml index 85fe2b2..38429e3 100644 --- a/asterisk/config.yaml +++ b/asterisk/config.yaml @@ -3,7 +3,7 @@ version: 4.0.0 slug: asterisk description: PBX server for SIP devices like doorbells and phones url: https://github.com/TECH7Fox/asterisk-hass-addons -image: "ghcr.io/tech7fox/{arch}-addon-asterisk" +image: ghcr.io/tech7fox/asterisk-hass-addon arch: - armhf - armv7 From 1bd30551bfdded5ceab2e0ede93399bf390217dd Mon Sep 17 00:00:00 2001 From: Felipe Santos Date: Thu, 23 Mar 2023 00:56:53 -0300 Subject: [PATCH 07/12] Improve changelog and docs --- asterisk/CHANGELOG.md | 6 +++++- asterisk/DOCS.md | 2 ++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/asterisk/CHANGELOG.md b/asterisk/CHANGELOG.md index 6622fe0..c8740f7 100644 --- a/asterisk/CHANGELOG.md +++ b/asterisk/CHANGELOG.md @@ -15,7 +15,11 @@ Make sure to check the add-on configuration page after updating the add-on to en ### New Features -Now the add-on can be run as a standalone docker container. +Now the add-on can be run as a standalone docker container: + +```console +docker pull ghcr.io/tech7fox/asterisk-hass-addon:4.0.0 +``` - An example `docker-compose.yml` file is available [here](../docker-compose.yaml). - Make sure to mount a `config` folder to `/config` and a `media` folder to `/media` to ensure the add-on can access your configuration and media files. diff --git a/asterisk/DOCS.md b/asterisk/DOCS.md index 43215fe..e7bd348 100644 --- a/asterisk/DOCS.md +++ b/asterisk/DOCS.md @@ -14,6 +14,8 @@ Follow these steps to get the add-on installed on your system: 1. Scroll down the page to find the new repository, and click in the new add-on named **_Asterisk_**. 1. Click in the **_INSTALL_** button. +Or you can also use it as a standalone docker container. See [4.0.0 release notes](./CHANGELOG.md#400) for more information. + ## Using 1. The certificate to your registered domain should already be created via the [Duck DNS](https://github.com/home-assistant/hassio-addons/tree/master/duckdns) or [Let's Encrypt](https://github.com/home-assistant/hassio-addons/tree/master/letsencrypt) add-on or another method. Make sure that the certificate files exist in the `/ssl/` directory. From 016f117711db122cf725ba5fb6ce95ad9e88e5b2 Mon Sep 17 00:00:00 2001 From: Felipe Santos Date: Thu, 23 Mar 2023 01:04:37 -0300 Subject: [PATCH 08/12] Fix docker labels --- asterisk/Dockerfile | 6 ++++++ asterisk/build.yaml | 5 ----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/asterisk/Dockerfile b/asterisk/Dockerfile index a4029ac..af96009 100644 --- a/asterisk/Dockerfile +++ b/asterisk/Dockerfile @@ -291,3 +291,9 @@ ENV S6_CMD_WAIT_FOR_SERVICES=0 ENTRYPOINT [ "/entrypoint.sh" ] CMD [ "/stdin.sh" ] + +LABEL \ + org.opencontainers.image.title="Home Assistant Add-on: Asterisk" \ + org.opencontainers.image.description="PBX server for SIP devices like doorbells and phones." \ + org.opencontainers.image.source="https://github.com/TECH7Fox/asterisk-hass-addons" \ + org.opencontainers.image.licenses="MIT" diff --git a/asterisk/build.yaml b/asterisk/build.yaml index 6174b93..a90b657 100644 --- a/asterisk/build.yaml +++ b/asterisk/build.yaml @@ -4,8 +4,3 @@ build_from: armhf: ghcr.io/hassio-addons/debian-base:6.2.3 armv7: ghcr.io/hassio-addons/debian-base:6.2.3 i386: ghcr.io/hassio-addons/debian-base:6.2.3 -labels: - org.opencontainers.image.title: "Home Assistant Add-on: Asterisk" - org.opencontainers.image.description: "PBX server for SIP devices like doorbells and phones." - org.opencontainers.image.source: "https://github.com/TECH7Fox/asterisk-hass-addons" - org.opencontainers.image.licenses: "MIT" From 2f15bce3b46b50da7b30470ca5a2af12f6cb6e57 Mon Sep 17 00:00:00 2001 From: Felipe Santos Date: Thu, 23 Mar 2023 01:30:22 -0300 Subject: [PATCH 09/12] Recreate workflow with support for multi-platform --- .github/workflows/builder.yaml | 139 ++++++++++----------------------- .github/workflows/lint.yaml | 2 - 2 files changed, 40 insertions(+), 101 deletions(-) diff --git a/.github/workflows/builder.yaml b/.github/workflows/builder.yaml index aa5a31e..076673e 100644 --- a/.github/workflows/builder.yaml +++ b/.github/workflows/builder.yaml @@ -1,118 +1,59 @@ -name: Builder - -env: - BUILD_ARGS: "" - MONITORED_FILES: "build.yaml config.yaml Dockerfile rootfs" +name: ci on: push: branches: - - main + - "main" + tags: + - "v*" pull_request: branches: - - main - - develop + - "main" jobs: - init: - runs-on: ubuntu-latest - name: Initialize builds - outputs: - changed_addons: ${{ steps.changed_addons.outputs.addons }} - changed: ${{ steps.changed_addons.outputs.changed }} - steps: - - name: Check out the repository - uses: actions/checkout@v3 - - - name: Get changed files - id: changed_files - uses: jitterbit/get-changed-files@v1 - - - name: Find add-on directories - id: addons - uses: home-assistant/actions/helpers/find-addons@master - - - name: Get changed add-ons - id: changed_addons - run: | - declare -a changed_addons - for addon in ${{ steps.addons.outputs.addons }}; do - if [[ "${{ steps.changed_files.outputs.all }}" =~ $addon ]]; then - for file in ${{ env.MONITORED_FILES }}; do - if [[ "${{ steps.changed_files.outputs.all }}" =~ $addon/$file ]]; then - if [[ ! "${changed_addons[@]}" =~ $addon ]]; then - changed_addons+=("\"${addon}\","); - fi - fi - done - fi - done - - changed=$(echo ${changed_addons[@]} | rev | cut -c 2- | rev) - - if [[ -n ${changed} ]]; then - echo "Changed add-ons: $changed"; - echo "::set-output name=changed::true"; - echo "::set-output name=addons::[$changed]"; - else - echo "No add-on had any monitored files changed (${{ env.MONITORED_FILES }})"; - fi - build: - needs: init + docker: runs-on: ubuntu-latest - if: needs.init.outputs.changed == 'true' - name: Build ${{ matrix.arch }} ${{ matrix.addon }} add-on - strategy: - fail-fast: false - matrix: - addon: ${{ fromJson(needs.init.outputs.changed_addons) }} - arch: ["aarch64", "amd64", "armhf", "armv7", "i386"] - steps: - - name: Check out repository + - name: Checkout uses: actions/checkout@v3 - - - name: Get information - id: info - uses: home-assistant/actions/helpers/info@master + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + - name: Get lowercase GitHub username + id: repository_owner + uses: ASzc/change-string-case-action@v5 with: - path: "./${{ matrix.addon }}" - - - name: Check if add-on should be built - id: check - run: | - if [[ "${{ steps.info.outputs.architectures }}" =~ ${{ matrix.arch }} ]]; then - echo "::set-output name=build_arch::true"; - echo "::set-output name=image::$(echo ${{ steps.info.outputs.image }} | cut -d'/' -f3)"; - if [[ "${{ github.event_name }}" == "pull_request" ]]; then - echo "BUILD_ARGS=--version pr-${{ github.event.number }}" >> $GITHUB_ENV; - fi - else - echo "${{ matrix.arch }} is not a valid arch for ${{ matrix.addon }}, skipping build"; - echo "::set-output name=build_arch::false"; - fi - - - name: Login to GitHub Container Registry + string: ${{ github.repository_owner }} + - name: Docker meta + id: meta + uses: docker/metadata-action@v4 + with: + images: | + ghcr.io/${{ steps.repository_owner.outputs.lowercase }}/asterisk-hass-addon + tags: | + type=ref,event=branch + type=ref,event=pr + type=semver,pattern={{version}} + + - name: Login to DockerHub + if: github.event_name == 'push' || github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]' uses: docker/login-action@v2 with: registry: ghcr.io username: ${{ github.repository_owner }} password: ${{ secrets.GITHUB_TOKEN }} - - name: Get lowercase GitHub username - id: repository_owner - uses: ASzc/change-string-case-action@v5 - with: - string: ${{ github.repository_owner }} - - - name: Build ${{ matrix.addon }} add-on - if: steps.check.outputs.build_arch == 'true' - uses: home-assistant/builder@2023.03.0 + - name: Build and push + uses: docker/build-push-action@v4 with: - args: | - ${{ env.BUILD_ARGS }} \ - --${{ matrix.arch }} \ - --target /data/${{ matrix.addon }} \ - --image "${{ steps.check.outputs.image }}" \ - --docker-hub "ghcr.io/${{ steps.repository_owner.outputs.lowercase }}" \ - --addon + context: asterisk + platforms: | + linux/amd64 + linux/386 + linux/arm/v6 + linux/arm/v7 + linux/arm64 + push: ${{ github.event_name == 'push' || github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]' }} + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 6025321..9529916 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -7,8 +7,6 @@ on: pull_request: branches: - main - schedule: - - cron: "0 0 * * *" jobs: find: From 9645aedf34b461ce52359e0ec6b601b6fb235f47 Mon Sep 17 00:00:00 2001 From: Felipe Santos Date: Thu, 23 Mar 2023 01:30:33 -0300 Subject: [PATCH 10/12] Add felipecrs to funding of add-on --- .github/FUNDING.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 52ff00f..6cef20a 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1 +1 @@ -github: [TECH7Fox] +github: [TECH7Fox, felipecrs] From c90a0e079449819ddcf5c06fc85a68d4ebfb25e8 Mon Sep 17 00:00:00 2001 From: Felipe Santos Date: Thu, 23 Mar 2023 01:33:16 -0300 Subject: [PATCH 11/12] Cancel CI jobs in progress --- .github/workflows/builder.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/builder.yaml b/.github/workflows/builder.yaml index 076673e..64d17b3 100644 --- a/.github/workflows/builder.yaml +++ b/.github/workflows/builder.yaml @@ -10,6 +10,10 @@ on: branches: - "main" +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + jobs: docker: runs-on: ubuntu-latest From 993f9116b1816adf169d3197d2378950a6e7fbee Mon Sep 17 00:00:00 2001 From: Felipe Santos Date: Thu, 23 Mar 2023 01:36:57 -0300 Subject: [PATCH 12/12] Add docker build caching to speed up ci --- .github/workflows/builder.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/builder.yaml b/.github/workflows/builder.yaml index 64d17b3..4f4bdbd 100644 --- a/.github/workflows/builder.yaml +++ b/.github/workflows/builder.yaml @@ -61,3 +61,5 @@ jobs: push: ${{ github.event_name == 'push' || github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]' }} tags: ${{ steps.meta.outputs.tags }} labels: ${{ steps.meta.outputs.labels }} + cache-from: type=gha + cache-to: type=gha,mode=max