From 7b102eca123c3864586b6f155c4412828073b88f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Bonelle?= Date: Wed, 3 Dec 2025 16:29:29 +0100 Subject: [PATCH] fix --- promtail/.DS_Store | Bin 6148 -> 0 bytes promtail/DOCS.md | 327 ------------------ promtail/Dockerfile | 67 ---- promtail/apparmor.txt | 123 ------- promtail/build.yaml | 10 - promtail/config.yaml | 39 --- promtail/icon.png | Bin 19951 -> 0 bytes promtail/logo.png | Bin 15536 -> 0 bytes promtail/rootfs/.DS_Store | Bin 6148 -> 0 bytes promtail/rootfs/etc/.DS_Store | Bin 6148 -> 0 bytes .../rootfs/etc/cont-init.d/promtail_setup.sh | 129 ------- promtail/rootfs/etc/promtail/base_config.yaml | 11 - .../etc/promtail/default-scrape-config.yaml | 27 -- .../rootfs/etc/services.d/promtail/finish | 15 - promtail/rootfs/etc/services.d/promtail/run | 40 --- 15 files changed, 788 deletions(-) delete mode 100644 promtail/.DS_Store delete mode 100644 promtail/DOCS.md delete mode 100644 promtail/Dockerfile delete mode 100644 promtail/apparmor.txt delete mode 100644 promtail/build.yaml delete mode 100644 promtail/config.yaml delete mode 100644 promtail/icon.png delete mode 100644 promtail/logo.png delete mode 100644 promtail/rootfs/.DS_Store delete mode 100644 promtail/rootfs/etc/.DS_Store delete mode 100755 promtail/rootfs/etc/cont-init.d/promtail_setup.sh delete mode 100644 promtail/rootfs/etc/promtail/base_config.yaml delete mode 100644 promtail/rootfs/etc/promtail/default-scrape-config.yaml delete mode 100755 promtail/rootfs/etc/services.d/promtail/finish delete mode 100755 promtail/rootfs/etc/services.d/promtail/run diff --git a/promtail/.DS_Store b/promtail/.DS_Store deleted file mode 100644 index f2c42ffe6e18fdaa374b3bd1197adbd4db00ebee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHKOA5k33{6x-aMPvBxq>$sL{H!aM8%a*@U!pAb9pphJ_u6X2yW!1ByT3oo6@&v z8WGXObw3wrL}UUtl$(XV*?se#4KkxZIL;EhG zhxz}N#2po&0)M4|j+X1?0x0*ZL3~Q$#csmAqJI2P^@yv^&uGkv) WYhoAZbmW~5:@logs-prod-us-central1.grafana.net/api/prom/push` -([see here for more info][grafana-cloud-docs-promtail]). - -### Option: `client.username` - -The username to use if you require basic auth to connect to your Loki deployment. - -### Option: `client.password` - -The password for the username you choose if you require basic auth to connect to -your Loki deployment. **Note**: This field is required if `client.username` is -provided. - -### Option: `client.cafile` - -The CA certificate used to sign Loki's certificate if Loki is using a self-signed -certificate for SSL. - -**Note**: _The file MUST be stored in `/ssl/`, which is the default_ - -### Option: `client.servername` - -The servername listed on the certificate Loki is using if using SSL to connect -by a different URL then what's on Loki's certificate (usually if the certificate -lists a public URL and you're connecting locally). - -### Option: `client.certfile` - -The absolute path to a certificate for client-authentication if Loki is using -mTLS to authenticate clients. - -### Option: `client.keyfile` - -The absolute path to the key for the client-authentication certificate if Loki -is using mTLS to authenticate clients. **Note**: This field is required if -`client.certfile` is provided - -### Option: `additional_pipeline_stages` - -The absolute path to a YAML file with a list of additional pipeline stages to -apply to the [default journal scrape config][addon-default-config]. The primary -use of this is to apply additional processing to logs from particular add-ons -you use if they are noisy or difficult to read. - -This file must contain only a YAML list of pipeline stages. They will be added -to the end of the ones already listed. If you don't like the ones listed, use -`skip_default_scrape_config` and `additional_scrape_configs` to write your own -instead. Here's an example of the contents of this file: - -```yaml -- match: - selector: '{container_name="addon_cebe7a76_hassio_google_drive_backup"}' - stages: - - multiline: - firstline: '^\x{001b}' -``` - -This particular example applies to the [google drive backup addon][addon-google-drive-backup]. -It uses the same log format as Home Assistant and outputs the escape character -at the start of each log line for color-coding in terminals. Looking for that -in a multiline stage makes it so tracebacks are included in the same log entry -as the error that caused them for easier readability. - -See the [promtail documentation][promtail-doc-stages] for more information on how -to configure pipeline stages. - -**Note**: This addon has access to `/ssl`, `/share` and `/config/promtail`. Place -the file in one of these locations, others will not work. - -### Option: `skip_default_scrape_config` - -Promtail will scrape the `systemd journal` using a pre-defined config you can -find [here][addon-default-config]. If you only want it to look at specific log -files you specify or you don't like the default config and want to adjust it, set -this to `true`. Then the only scrape configs used will be the ones you specify -in the `additional_scrape_configs` file. - -**Note**: This addon has access to `/ssl`, `/share` and `/config/promtail`. Place -the file in one of these locations, others will not work. - -### Option: `additional_scrape_configs` - -The absolute path to a YAML file with a list of additional scrape configs for -Promtail to use. The primary use of this is to point Promtail at additional log -files created by add-ons which don't use `stdout` for all logging. You an also -change the system journal is scraped by using this in conjunction with -`skip_default_scrape_config`. **Note**: If `skip_default_scrape_config` is `true` -then this field becomes required (otherwise there would be no scrape configs) - -The file must contain only a YAML list of scrape configs. Here's an example of -the contents of this file: - -```yaml -- job_name: zigbee2mqtt_messages - pipeline_stages: - static_configs: - - targets: - - localhost - labels: - job: zigbee2mqtt_messages - __path__: /share/zigbee2mqtt/log/**.txt -``` - -This particular example would cause Promtail to scrape up the logs MQTT that the -[Zigbee2MQTT add-on][addon-z2m] makes by default. - -Promtail provides a lot of options for configuring scrape configs. See the -documentation on [scrape_configs][promtail-doc-scrape-configs] for more info on -the options available and how to configure them. The documentation also provides -[other examples][promtail-doc-examples] you can use. - -I would also recommend reading the [Loki best practices][loki-doc-best-practices] -guide before making custom scrape configs. Pipelines are pretty powerful but -avoid making too many labels, it does more harm then good. Instead look into -what you can do with [LogQL][logql] can do at the other end. - -**Note**: This addon has access to `/ssl`, `/share` and `/config/promtail`. Place -the file in one of these locations, others will not work. - -### Port: `9080/tcp` - -Promtail expose an [API][api] on this port. This is primarily used for healthchecks -by the supervisor watchdog which does not require exposing it on the host. Most -users should leave this option disabled unless you have an external application -doing healthchecks. - -For advanced users creating custom scrape configs the other purpose of this API -is to expose metrics created by the [metrics][promtail-doc-metrics] pipeline -stage. Exposing this port would then allow you to read those metrics from another -system on your network. - -### 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: - -- `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. - -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. - -## PLG Stack (Promtail, Loki and Grafana) - -Promtail isn't a standalone application, it's job is to find logs, process them -and ship them to Loki. Most likely you want the full PLG stack: - -- Promtail to process and ship logs -- Loki to aggregate and index them -- Grafana to visualize and monitor them - -### Loki - -The easiest way to get started is to also install the Loki add-on in this same -repository. By default this add-on is set up to collect all logs from the system -journal and ship them over to that add-on. If that's what you want there is no -additional configuration required for either. - -[![Open your Home Assistant instance and show the dashboard of a Supervisor add-on.][add-addon-shield]][add-addon-loki] - -Alternatively you can deploy Loki somewhere else. Take a look at the -[Loki documentation][loki-doc] for info on setting up a Loki deployment and -connecting Promtail to it. - -### Grafana - -Once you have Loki and Promtail set up you will probably want to connect to it -from [Grafana][grafana]. The easiest way to do that is to use the -[Grafana community add-on][addon-grafana]. From there you can find Loki in the -list of data sources and configure the connection (see [Loki in Grafana][loki-in-grafana]). -If you did choose to use the Loki add-on you can find additional instructions in -[the add-on's documentation][addon-loki-doc]. - -[![Open your Home Assistant instance and show the dashboard of a Supervisor add-on.][add-addon-shield]][add-addon-grafana] - -### Grafana Cloud - -If you prefer, you can also use Grafana's cloud service, -[see here](https://grafana.com/products/cloud/) on how to get started. This -service takes the place of both Loki and Grafana in the PLG stack, you just -point Promtail at it and you're done. To do this, first create an account then -[review this guide][grafana-cloud-docs-promtail] to see how to connect Promtail -to your account. Essentially its just a different URL since the credential information -goes in the URL. - -## 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 ways to get them answered: - -- The Home Assistant [Community Forum][forum]. I am - [CentralCommand][forum-centralcommand] there. -- The Home Assistant [Discord Chat Server][discord-ha]. Use the #add-ons channel, - I am CentralCommand#0913 there. - -You could also [open an issue here][issue] on GitHub. - -## Authors & contributors - -The original setup of this repository is by [Mike Degatano][mdegat01]. - -For a full list of all authors and contributors, -check [the contributor's page][contributors]. - -## License - -MIT License - -Copyright (c) 2021-2022 Mike Degatano - -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. - -[add-addon-shield]: https://my.home-assistant.io/badges/supervisor_addon.svg -[add-addon]: https://my.home-assistant.io/redirect/supervisor_addon/?addon=39bd2704_promtail -[add-addon-grafana]: https://my.home-assistant.io/redirect/supervisor_addon/?addon=a0d7b954_grafana -[add-addon-loki]: https://my.home-assistant.io/redirect/supervisor_addon/?addon=39bd2704_loki -[add-repo-shield]: https://my.home-assistant.io/badges/supervisor_add_addon_repository.svg -[add-repo]: https://my.home-assistant.io/redirect/supervisor_add_addon_repository/?repository_url=https%3A%2F%2Fgithub.com%2Fmdegat01%2Fhassio-addons -[addon-default-config]: https://github.com/mdegat01/addon-promtail/blob/main/promtail/rootfs/etc/promtail/default-scrape-config.yaml -[addon-grafana]: https://github.com/hassio-addons/addon-grafana -[addon-google-drive-backup]: https://github.com/sabeechen/hassio-google-drive-backup -[addon-loki-doc]: https://github.com/mdegat01/addon-loki/blob/main/loki/DOCS.md#grafana -[addon-z2m]: https://github.com/zigbee2mqtt/hassio-zigbee2mqtt -[api]: https://grafana.com/docs/loki/latest/clients/promtail/#api -[contributors]: https://github.com/mdegat01/addon-promtail/graphs/contributors -[discord-ha]: https://discord.gg/c5DvZ4e -[forum-centralcommand]: https://community.home-assistant.io/u/CentralCommand/?u=CentralCommand -[forum]: https://community.home-assistant.io/t/home-assistant-add-on-promtail/293732?u=CentralCommand -[grafana]: https://grafana.com/oss/grafana/ -[grafana-cloud]: https://grafana.com/products/cloud/ -[grafana-cloud-docs-promtail]: https://grafana.com/docs/grafana-cloud/quickstart/logs_promtail_linuxnode/ -[issue]: https://github.com/mdegat01/addon-promtail/issues -[logql]: https://grafana.com/docs/loki/latest/logql/ -[loki-doc]: https://grafana.com/docs/loki/latest/overview/ -[loki-doc-best-practices]: https://grafana.com/docs/loki/latest/best-practices/ -[loki-in-grafana]: https://grafana.com/docs/loki/latest/getting-started/grafana/ -[mdegat01]: https://github.com/mdegat01 -[promtail-doc-examples]: https://grafana.com/docs/loki/latest/clients/promtail/configuration/#example-static-config -[promtil-doc-metrics]: https://grafana.com/docs/loki/latest/clients/promtail/configuration/#metrics -[promtail-doc-scrape-configs]: https://grafana.com/docs/loki/latest/clients/promtail/configuration/#scrape_configs -[promtail-doc-stages]: https://grafana.com/docs/loki/latest/clients/promtail/stages/ -[releases]: https://github.com/mdegat01/addon-promtail/releases -[semver]: http://semver.org/spec/v2.0.0 diff --git a/promtail/Dockerfile b/promtail/Dockerfile deleted file mode 100644 index 9ffbba6..0000000 --- a/promtail/Dockerfile +++ /dev/null @@ -1,67 +0,0 @@ -ARG BUILD_FROM -FROM ${BUILD_FROM} - -# Build arguments -ARG BUILD_ARCH -ARG BUILD_DATE -ARG BUILD_DESCRIPTION -ARG BUILD_NAME -ARG BUILD_REF -ARG BUILD_REPOSITORY -ARG BUILD_VERSION -ARG YQ_VERSION -ARG PROMTAIL_VERSION - -# Add yq and tzdata (required for the timestamp stage) -RUN set -eux; \ - apt-get update; \ - apt-get install -qy --no-install-recommends \ - tar \ - unzip \ - libsystemd-dev \ - ; \ - update-ca-certificates; \ - case "${BUILD_ARCH}" in \ - amd64) BINARCH='amd64' ;; \ - armhf) BINARCH='arm' ;; \ - armv7) BINARCH='arm' ;; \ - aarch64) BINARCH='arm64' ;; \ - *) echo >&2 "error: unsupported architecture (${APKARCH})"; exit 1 ;; \ - esac; \ - curl -s -J -L -o /tmp/yq.tar.gz \ - "https://github.com/mikefarah/yq/releases/download/v${YQ_VERSION}/yq_linux_${BINARCH}.tar.gz"; \ - tar -xf /tmp/yq.tar.gz -C /usr/bin; \ - mv /usr/bin/yq_linux_${BINARCH} /usr/bin/yq; \ - chmod a+x /usr/bin/yq; \ - rm /tmp/yq.tar.gz; \ - yq --version; \ - apt-get clean; \ - rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*; \ - curl -s -J -L -o /tmp/promtail.zip \ - "https://github.com/grafana/loki/releases/download/v${PROMTAIL_VERSION}/promtail-linux-${BINARCH}.zip"; \ - unzip /tmp/promtail.zip -d /usr/bin; \ - mv /usr/bin/promtail-linux-${BINARCH} /usr/bin/promtail; \ - chmod +x /usr/bin/promtail; \ - rm /tmp/promtail.zip; \ - mkdir -p /data/promtail; \ - rm -rf /var/lib/apt/lists/* - -COPY rootfs / -WORKDIR /data/promtail - -# Labels -LABEL \ - io.hass.name="${BUILD_NAME}" \ - io.hass.description="${BUILD_DESCRIPTION}" \ - io.hass.arch="${BUILD_ARCH}" \ - io.hass.type="addon" \ - io.hass.version=${BUILD_VERSION} \ - maintainer="fbonelle" \ - org.opencontainers.image.title="${BUILD_NAME}" \ - org.opencontainers.image.description="${BUILD_DESCRIPTION}" \ - org.opencontainers.image.vendor="fbonelle's addons" \ - org.opencontainers.image.authors="fbonelle" \ - org.opencontainers.image.licenses="MIT" \ - org.opencontainers.image.created=${BUILD_DATE} \ - org.opencontainers.image.revision=${BUILD_REF} \ - org.opencontainers.image.version=${BUILD_VERSION} \ No newline at end of file diff --git a/promtail/apparmor.txt b/promtail/apparmor.txt deleted file mode 100644 index 910a878..0000000 --- a/promtail/apparmor.txt +++ /dev/null @@ -1,123 +0,0 @@ -include - -# Docker overlay -@{docker_root}=/docker/ /var/lib/docker/ -@{fs_root}=/ @{docker_root}/overlay2/*/diff/ -@{do_etc}=@{fs_root}/etc/ -@{do_opt}=@{fs_root}/opt/ -@{do_run}=@{fs_root}/{run,var/run}/ -@{do_usr}=@{fs_root}/usr/ -@{do_var}=@{fs_root}/var/ - -# Systemd Journal location -@{journald}=/{run,var}/log/journal/{,**} - -profile hassio_promtail flags=(attach_disconnected,mediate_deleted) { - include - include - - # Send signals to child services - signal (send) peer=@{profile_name}//*, - - # Network access - network tcp, - network udp, - - # S6-Overlay - /init rix, - /bin/** rix, - @{do_usr}/bin/** rix, - @{do_usr}/sbin/** rix, - @{do_usr}/share/{,**} r, - @{do_usr}/lib/locale/{,**} r, - @{do_etc}/* rw, - @{do_etc}/s6*/** r, - @{do_etc}/fix-attrs.d/{,**} r, - @{do_etc}/cont-{init,finish}.d/{,**} rwix, - @{do_etc}/services.d/{,**} rwix, - @{do_etc}/ssl/openssl.cnf r, - @{do_etc}/{group,hosts,passwd} r, - @{do_etc}/{host,nsswitch,resolv}.conf r, - @{do_run}/{s6,s6-rc*,service}/** rix, - @{do_run}/{,**} rwk, - /var/cache/{,**} rw, - /dev/tty rw, - /dev/null k, - /command/** rix, - /package/** rix, - - - # Bashio - @{do_usr}/lib/bashio/** ix, - /tmp/** rw, - - # Options.json & addon data - /data r, - /data/** rw, - - # Files needed for setup - @{do_etc}/promtail/{,**} rw, - /config/promtail/{,**} r, - /{share,ssl}/{,**} r, - @{journald} r, - - # Programs - /usr/bin/promtail cx -> promtail_profile, - /usr/bin/yq Cx -> yq_profile, - /usr/sbin/dpkg-reconfigure Cx -> dpkg_reconfigure_profile, - - profile promtail_profile flags=(attach_disconnected,mediate_deleted) { - include - - # Receive signals from s6 - signal (receive) peer=*_promtail, - - # Network access - network tcp, - network udp, - network netlink raw, - network unix dgram, - - # Temp files - /tmp/.positions.yaml* rw, - - # Addon data - /data/** r, - /data/promtail/** rwk, - - # Config & log data - @{do_etc}/promtail/config.yaml r, - /config/promtail/{,**} r, - /{share,ssl}/** r, - @{journald} r, - - # Runtime usage - /usr/bin/promtail rm, - @{do_etc}/{hosts,passwd} r, - @{do_etc}/{resolv,nsswitch}.conf r, - @{PROC}/sys/net/core/somaxconn r, - @{sys}/kernel/mm/transparent_hugepage/hpage_pmd_size r, - /dev/null k, - @{do_etc}/ssl/certs/** r, - } - - profile yq_profile flags=(attach_disconnected,mediate_deleted) { - include - - # Config files - @{do_etc}/promtail/* rw, - /config/promtail/{,**} r, - /share/** r, - - # Runtime usage - /usr/bin/yq rm, - @{sys}/kernel/mm/transparent_hugepage/hpage_pmd_size r, - /dev/null k, - } - - profile dpkg_reconfigure_profile flags=(attach_disconnected,mediate_deleted) { - include - - /** rwlkmix, - } -} \ No newline at end of file diff --git a/promtail/build.yaml b/promtail/build.yaml deleted file mode 100644 index e8c2a29..0000000 --- a/promtail/build.yaml +++ /dev/null @@ -1,10 +0,0 @@ ---- -build_from: - aarch64: ghcr.io/hassio-addons/debian-base:8.1.4 - amd64: ghcr.io/hassio-addons/debian-base:8.1.4 - armhf: ghcr.io/hassio-addons/debian-base:8.1.4 - armv7: ghcr.io/hassio-addons/debian-base:8.1.4 - i386: ghcr.io/hassio-addons/debian-base:8.1.4 -args: - YQ_VERSION: 4.48.1 - PROMTAIL_VERSION: 3.5.7 \ No newline at end of file diff --git a/promtail/config.yaml b/promtail/config.yaml deleted file mode 100644 index 8dd8d9a..0000000 --- a/promtail/config.yaml +++ /dev/null @@ -1,39 +0,0 @@ ---- -name: Promtail -url: https://gitea.bonelle-family.dscloud.biz/francois.bonelle/hassio-repo.git -version: 3.5.7 -slug: hassio_promtail -arch: - - aarch64 - - amd64 - - armv7 - - armhf -description: Promtail for Home Assistant -init: false -journald: true -map: - - config - - share - - ssl -watchdog: http://[HOST]:[PORT:9080]/ready -ports: - 9080/tcp: -ports_description: - 9080/tcp: Promtail web server -options: - client: - url: http://loki:3100/loki/api/v1/push - log_level: info -schema: - client: - url: str - username: str? - password: password? - cafile: str? - servername: str? - certfile: str? - keyfile: str? - additional_pipeline_stages: str? - additional_scrape_configs: str? - skip_default_scrape_config: bool? - log_level: list(trace|debug|info|notice|warning|error|fatal)? diff --git a/promtail/icon.png b/promtail/icon.png deleted file mode 100644 index 8e89cb402b223120536b78eda23e49ee6f758705..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19951 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 CjNU~6 diff --git a/promtail/rootfs/.DS_Store b/promtail/rootfs/.DS_Store deleted file mode 100644 index e412cbf315ed784cd3fe292626826499981feea3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeH~I}XA?3`A|9K%z-WxeW*41}g+7-~xzG7bykM@6j258Ui(n&{(qH+8Zm$6xmor zboab&MLH2#!i}=AFfv6xmzzA~a=l;r^Dy*Qa+@Ws0Pke9pW6f#paN8Y3Qz$mFd+r< zAYZN~^h|sdDnJFMp@4lK3fx$eE$E*P1Rnvw1lA49C} z?O@64YO)2RT{MRe%{!}2F))pG(Sih~)xkgosK7{pdE}j){|ETD`G3^HlnPLRKT|*# z`{RCxm&&vCmkP$=mJD%iSj_{K_kFuu&#$CukI`B?1u`L@eu$xL)Z<^K1%?L1%NfN4@3l}K?Md?bHvb~BVIDECia0r7xl`xCo5}C zDC*S_FP<)11G!QGDsZd7V{Dh!|F`fv^ZzZ0J1Rg0{*?kc+w3-Lyi)eo(aTw{E$}`3 q$B^skSiBVjy%l3)t#~!aEB1`@n%D> "${CONFIG_FILE}" -fi - -if ! bashio::config.is_empty 'client.cafile'; then - bashio::log.info "Adding TLS to client config..." - cafile="/ssl/$(bashio::config 'client.cafile')" - - if ! bashio::fs.file_exists "${cafile}"; then - bashio::log.fatal - bashio::log.fatal "The file specified for 'cafile' does not exist!" - bashio::log.fatal "Ensure the CA certificate file exists and full path is provided" - bashio::log.fatal - bashio::exit.nok - fi - { - echo " tls_config:" - echo " ca_file: ${cafile}" - } >> "${CONFIG_FILE}" - - if ! bashio::config.is_empty 'client.servername'; then - echo " server_name: $(bashio::config 'client.servername')" >> "${CONFIG_FILE}" - fi - - if ! bashio::config.is_empty 'client.certfile'; then - bashio::log.info "Adding mTLS to client config..." - bashio::config.require 'client.keyfile' "'client.certfile' is specified" - if ! bashio::fs.file_exists "$(bashio::config 'client.certfile')"; then - bashio::log.fatal - bashio::log.fatal "The file specified for 'certfile' does not exist!" - bashio::log.fatal "Ensure the certificate file exists and full path is provided" - bashio::log.fatal - bashio::exit.nok - fi - if ! bashio::fs.file_exists "$(bashio::config 'client.keyfile')"; then - bashio::log.fatal - bashio::log.fatal "The file specified for 'keyfile' does not exist!" - bashio::log.fatal "Ensure the key file exists and full path is provided" - bashio::log.fatal - bashio::exit.nok - fi - { - echo " cert_file: $(bashio::config 'client.certfile')" - echo " key_file: $(bashio::config 'client.keyfile')" - } >> "${CONFIG_FILE}" - fi -fi - -# Add in scrape configs -{ - echo - echo "scrape_configs:" -} >> "${CONFIG_FILE}" -if bashio::config.true 'skip_default_scrape_config'; then - bashio::log.info 'Skipping default journald scrape config...' - if ! bashio::config.is_empty 'additional_pipeline_stages'; then - bashio::log.warning - bashio::log.warning "'additional_pipeline_stages' ignored since 'skip_default_scrape_config' is true!" - bashio::log.warning 'See documentation for more information.' - bashio::log.warning - fi - bashio::config.require 'additional_scrape_configs' "'skip_default_scrape_config' is true" - -elif ! bashio::config.is_empty 'additional_pipeline_stages'; then - bashio::log.info "Adding additional pipeline stages to default journal scrape config..." - add_stages="$(bashio::config 'additional_pipeline_stages')" - scrape_configs="${CUSTOM_SCRAPE_CONFIGS}" - if ! bashio::fs.file_exists "${add_stages}"; then - bashio::log.fatal - bashio::log.fatal "The file specified for 'additional_pipeline_stages' does not exist!" - bashio::log.fatal "Ensure the file exists at the path specified" - bashio::log.fatal - bashio::exit.nok - fi - - yq -NP eval-all \ - 'select(fi == 0) + [{"add_pipeline_stages": select(fi == 1)}]' \ - "${DEF_SCRAPE_CONFIGS}" "${add_stages}" \ - | yq -NP e \ - '[(.[0] * .[1]) | {"job_name": .job_name, "journal": .journal, "relabel_configs": .relabel_configs, "pipeline_stages": .pipeline_stages + .add_pipeline_stages}]' \ - - > "${scrape_configs}" -fi - -if ! bashio::config.is_empty 'additional_scrape_configs'; then - bashio::log.info "Adding custom scrape configs..." - add_scrape_configs="$(bashio::config 'additional_scrape_configs')" - if ! bashio::fs.file_exists "${add_scrape_configs}"; then - bashio::log.fatal - bashio::log.fatal "The file specified for 'additional_scrape_configs' does not exist!" - bashio::log.fatal "Ensure the file exists at the path specified" - bashio::log.fatal - bashio::exit.nok - fi - - if bashio::config.true 'skip_default_scrape_config'; then - yq -NP e '[] + .' "${add_scrape_configs}" >> "${CONFIG_FILE}" - else - yq -NP eval-all 'select(fi == 0) + select(fi == 1)' \ - "${scrape_configs}" "${add_scrape_configs}" >> "${CONFIG_FILE}" - fi -else - yq -NP e '[] + .' "${scrape_configs}" >> "${CONFIG_FILE}" -fi diff --git a/promtail/rootfs/etc/promtail/base_config.yaml b/promtail/rootfs/etc/promtail/base_config.yaml deleted file mode 100644 index 0e6eb25..0000000 --- a/promtail/rootfs/etc/promtail/base_config.yaml +++ /dev/null @@ -1,11 +0,0 @@ ---- -server: - http_listen_port: 9080 - grpc_listen_port: 0 - log_level: "${LOG_LEVEL}" - -positions: - filename: /data/promtail/positions.yaml - -clients: - - url: "${URL}" diff --git a/promtail/rootfs/etc/promtail/default-scrape-config.yaml b/promtail/rootfs/etc/promtail/default-scrape-config.yaml deleted file mode 100644 index 6e3f112..0000000 --- a/promtail/rootfs/etc/promtail/default-scrape-config.yaml +++ /dev/null @@ -1,27 +0,0 @@ ---- -- job_name: journal - journal: - json: false - max_age: 12h - labels: - job: systemd-journal - path: "${JOURNAL_PATH}" - relabel_configs: - - source_labels: - - __journal__systemd_unit - target_label: unit - - source_labels: - - __journal__hostname - target_label: nodename - - source_labels: - - __journal_syslog_identifier - target_label: syslog_identifier - - source_labels: - - __journal_container_name - target_label: container_name - pipeline_stages: - - match: - selector: '{container_name=~"homeassistant|hassio_supervisor"}' - stages: - - multiline: - firstline: '^\x{001b}' diff --git a/promtail/rootfs/etc/services.d/promtail/finish b/promtail/rootfs/etc/services.d/promtail/finish deleted file mode 100755 index 649e4e5..0000000 --- a/promtail/rootfs/etc/services.d/promtail/finish +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bashio -# ============================================================================== -# Take down the S6 supervision tree when Promtail fails -# s6-overlay docs: https://github.com/just-containers/s6-overlay -# ============================================================================== - -declare APP_EXIT_CODE=${1} - -if [[ "${APP_EXIT_CODE}" -ne 0 ]] && [[ "${APP_EXIT_CODE}" -ne 256 ]]; then - bashio::log.warning "Halt add-on with exit code ${APP_EXIT_CODE}" - echo "${APP_EXIT_CODE}" > /run/s6-linux-init-container-results/exitcode - exec /run/s6/basedir/bin/halt -fi - -bashio::log.info "Service restart after closing" diff --git a/promtail/rootfs/etc/services.d/promtail/run b/promtail/rootfs/etc/services.d/promtail/run deleted file mode 100755 index d5f6a71..0000000 --- a/promtail/rootfs/etc/services.d/promtail/run +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/with-contenv bashio -# shellcheck shell=bash -# ============================================================================== -# Home Assistant Add-on: Promtail -# Runs Promtail -# ============================================================================== -readonly PROMTAIL_CONFIG='/etc/promtail/config.yaml' -declare log_level - -bashio::log.info 'Starting Promtail...' - -journal_path='/var/log/journal' -if ! bashio::fs.directory_exists "${journal_path}" || [ -z "$(ls -A ${journal_path})" ]; then - bashio::log.info "No journal at ${journal_path}, looking for journal in /run/log/journal instead" - journal_path='/run/log/journal' -fi - -case "$(bashio::config 'log_level')" in \ - trace) ;& \ - debug) log_level='debug' ;; \ - notice) ;& \ - warning) log_level='warn' ;; \ - error) ;& \ - fatal) log_level='error' ;; \ - *) log_level='info' ;; \ -esac; -bashio::log.info "Promtail log level set to ${log_level}" - -export "URL=$(bashio::config 'client.url')" -export "JOURNAL_PATH=${journal_path}" -export "LOG_LEVEL=${log_level}" - -promtail_args=("-config.expand-env=true" "-config.file=${PROMTAIL_CONFIG}") -if [ "${log_level}" == "debug" ]; then - bashio::log.debug "Logging full config on startup for debugging..." - promtail_args+=("-print-config-stderr=true") -fi - -bashio::log.info "Handing over control to Promtail..." -/usr/bin/promtail "${promtail_args[@]}"