updates2mqtt 1.3.5__tar.gz → 1.3.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/.pre-commit-config.yaml +2 -2
- updates2mqtt-1.3.7/CHANGELOG.md +12 -0
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/PKG-INFO +16 -138
- updates2mqtt-1.3.7/README.md +82 -0
- updates2mqtt-1.3.7/docs/configuration.md +98 -0
- updates2mqtt-1.3.7/docs/examples/config_maximal.md +7 -0
- updates2mqtt-1.3.7/docs/examples/config_minimal.md +7 -0
- updates2mqtt-1.3.7/docs/examples/docker_compose.md +7 -0
- updates2mqtt-1.3.7/docs/installation.md +29 -0
- updates2mqtt-1.3.7/docs/local_builds.md +22 -0
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/examples/config.yaml.maximal +3 -3
- updates2mqtt-1.3.7/examples/config.yaml.minimal +9 -0
- updates2mqtt-1.3.7/no_config.yaml +33 -0
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/pyproject.toml +6 -4
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/src/updates2mqtt/app.py +13 -5
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/src/updates2mqtt/config.py +18 -14
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/src/updates2mqtt/mqtt.py +16 -4
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/tests/test_config.py +19 -2
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/uv.lock +92 -92
- updates2mqtt-1.3.5/README.md +0 -206
- updates2mqtt-1.3.5/examples/config.yaml.minimal +0 -22
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/.dockerignore +0 -0
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/.github/dependabot.yml +0 -0
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/.github/workflows/docker-publish.yml +0 -0
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/.github/workflows/pypi-publish.yml +0 -0
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/.github/workflows/python-package.yml +0 -0
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/.gitignore +0 -0
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/.hintrc +0 -0
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/.python-version +0 -0
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/.safety-project.ini +0 -0
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/Dockerfile +0 -0
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/LICENSE +0 -0
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/SECURITY.md +0 -0
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/common_packages.yaml +0 -0
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/conftest.py +0 -0
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/docs/images/ha_mqtt_discovery.png +0 -0
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/docs/images/ha_update_detail.png +0 -0
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/docs/images/ha_update_page.png +0 -0
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/docs/index.md +0 -0
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/examples/docker-compose.yaml +0 -0
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/mkdocs.yml +0 -0
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/refresh-deps.sh +0 -0
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/scripts/healthcheck.sh +0 -0
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/src/updates2mqtt/__init__.py +0 -0
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/src/updates2mqtt/__main__.py +0 -0
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/src/updates2mqtt/hass_formatter.py +0 -0
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/src/updates2mqtt/integrations/__init__.py +0 -0
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/src/updates2mqtt/integrations/docker.py +0 -0
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/src/updates2mqtt/integrations/git_utils.py +0 -0
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/src/updates2mqtt/model.py +0 -0
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/src/updates2mqtt/py.typed +0 -0
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/tests/__init__.py +0 -0
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/tests/test_docker.py +0 -0
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/tests/test_git_utils.py +0 -0
- {updates2mqtt-1.3.5 → updates2mqtt-1.3.7}/tests/test_mqtt.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
repos:
|
|
2
2
|
- repo: https://github.com/asottile/pyupgrade
|
|
3
|
-
rev: v3.21.
|
|
3
|
+
rev: v3.21.1
|
|
4
4
|
hooks:
|
|
5
5
|
- id: pyupgrade
|
|
6
6
|
args: [--py313-plus]
|
|
@@ -17,7 +17,7 @@ repos:
|
|
|
17
17
|
- id: check-shebang-scripts-are-executable
|
|
18
18
|
name: Check shell scripts are executable
|
|
19
19
|
- repo: https://github.com/astral-sh/uv-pre-commit
|
|
20
|
-
rev: 0.9.
|
|
20
|
+
rev: 0.9.9
|
|
21
21
|
hooks:
|
|
22
22
|
- id: uv-lock
|
|
23
23
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# CHANGELOG
|
|
2
|
+
|
|
3
|
+
## 1.3.7
|
|
4
|
+
- Improved initial setup when run without config or env vars for MQTT
|
|
5
|
+
- Minor test deps update and pyproject docs
|
|
6
|
+
|
|
7
|
+
## 1.3.6
|
|
8
|
+
- Changed exit code on graceful shutdown to 143
|
|
9
|
+
- App now exits if the MQTT username / password is not authorized
|
|
10
|
+
- Improved handling of env vars, default config now assumes MQTT_HOST etc unless overridden
|
|
11
|
+
- Will now run without a config if correct `MQTT_HOST`,`MQTT_USER`,`MQTT_PASS`,`MQTT_PORT` env vars set or match the defaults (`127.0.0.1:1883`)
|
|
12
|
+
- Deps update
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: updates2mqtt
|
|
3
|
-
Version: 1.3.
|
|
3
|
+
Version: 1.3.7
|
|
4
4
|
Summary: System update and docker image notification and execution over MQTT
|
|
5
|
+
Project-URL: Homepage, https://updates2mqtt.rhizomatics.org.uk
|
|
5
6
|
Project-URL: Repository, https://github.com/rhizomatics/updates2mqtt
|
|
6
7
|
Project-URL: Documentation, https://updates2mqtt.rhizomatics.org.uk
|
|
7
8
|
Project-URL: Issues, https://github.com/rhizomatics/updates2mqtt/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/rhizomatics/updates2mqtt/blob/main/CHANGELOG.md
|
|
8
10
|
Author-email: jey burrows <jrb@rhizomatics.org.uk>
|
|
9
11
|
License-Expression: Apache-2.0
|
|
10
12
|
License-File: LICENSE
|
|
@@ -37,6 +39,7 @@ Description-Content-Type: text/markdown
|
|
|
37
39
|
|
|
38
40
|
# updates2mqtt
|
|
39
41
|
|
|
42
|
+
[](https://pypi.org/project/updates2mqtt/)
|
|
40
43
|
[](https://github.com/rhizomatics/supernotify)
|
|
41
44
|
[](https://results.pre-commit.ci/latest/github/rhizomatics/updates2mqtt/main)
|
|
42
45
|
[](https://github.com/rhizomatics/updates2mqtt/actions/workflows/pypi-publish.yml)
|
|
@@ -52,152 +55,25 @@ Use Home Assistant to notify you of updates to Docker images for your containers
|
|
|
52
55
|
|
|
53
56
|
## Description
|
|
54
57
|
|
|
55
|
-
updates2mqtt perioidically checks for new versions of components being available, and publishes new version info to MQTT.
|
|
56
|
-
HomeAssistant auto discovery is supported, so all updates can be seen in the same place as Home Assistant's
|
|
57
|
-
own components and add-ins.
|
|
58
|
+
updates2mqtt perioidically checks for new versions of components being available, and publishes new version info to MQTT. HomeAssistant auto discovery is supported, so all updates can be seen in the same place as Home Assistant's own components and add-ins.
|
|
58
59
|
|
|
59
|
-
Currently only Docker containers are supported, either via an image registry check, or a git repo for source. The design is modular, so other update sources can be added, at least for notification. The next anticipated is **apt** for Debian based systems.
|
|
60
|
+
Currently only Docker containers are supported, either via an image registry check, or a git repo for source (see [Local Builds](local_builds.md)). The design is modular, so other update sources can be added, at least for notification. The next anticipated is **apt** for Debian based systems.
|
|
60
61
|
|
|
61
|
-
Components can also be updated, either automatically or triggered via MQTT, for example by hitting the *Install*
|
|
62
|
-
button in the HomeAssistant update dialog. Icons and release notes can be specified for a better HA experience.
|
|
62
|
+
Components can also be updated, either automatically or triggered via MQTT, for example by hitting the *Install* button in the HomeAssistant update dialog. Icons and release notes can be specified for a better HA experience.
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
To get started, read the [Installation](installation.md) and [Configuration](configuration.md) pages.
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
### Manual - Run without installing using uv
|
|
69
|
-
```
|
|
70
|
-
uv run --with updates2mqtt updates2mqtt
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
### Manual - Install and run with pip
|
|
74
|
-
```
|
|
75
|
-
pip install updates2mqtt
|
|
76
|
-
python3 -m updates2mqtt
|
|
77
|
-
```
|
|
78
|
-
### Docker
|
|
79
|
-
|
|
80
|
-
See `examples` directory for a working `docker-compose.yaml`.
|
|
81
|
-
|
|
82
|
-
If you want to update and restart containers, then the file system paths to the location of the
|
|
83
|
-
directory where the docker compose file lives must be available in the updates2mqtt container.
|
|
84
|
-
|
|
85
|
-
The example `docker-compose.yaml` mounts `/home/containers` for this purpose, so if your containers are in
|
|
86
|
-
`/home/containers/app1`, `/home/containers/app2` etc, then updates2mqtt will be able to find them. Map as
|
|
87
|
-
many root paths as needed.
|
|
88
|
-
|
|
89
|
-
## Configuration
|
|
90
|
-
|
|
91
|
-
Create file `config.yaml` in `conf` directory. If the file is not present, a default file will be generated.
|
|
92
|
-
|
|
93
|
-
### Example configuration file
|
|
94
|
-
|
|
95
|
-
This is a maximal config file, the minimum is no config file at all, which will generate a default config file. The only mandatory values are the MQTT user name and password, everything else can be omitted.
|
|
66
|
+
For a quick spin, try this:
|
|
96
67
|
|
|
97
68
|
```yaml
|
|
98
|
-
|
|
99
|
-
node:
|
|
100
|
-
name: docker-host-1 # Unique name for this instance, used to name MQTT entities. Defaults to O/S hostname
|
|
101
|
-
git_repo_path: /usr/bin/git # Path to git inside container, needed only if non-default and using local docker builds
|
|
102
|
-
healthcheck:
|
|
103
|
-
enabled: true
|
|
104
|
-
interval: 300 # publish a heartbeat every 5 minutes
|
|
105
|
-
topic_template: healthcheck/{node_name}/updates2mqtt
|
|
106
|
-
mqtt:
|
|
107
|
-
host: ${oc.env:MQTT_HOST}
|
|
108
|
-
user: ${oc.env:MQTT_USER}
|
|
109
|
-
password: ${oc.env:MQTT_PASS}$ # Use an environment variable for secrets
|
|
110
|
-
port: ${oc.env:MQTT_PORT}
|
|
111
|
-
topic_root: updates2mqtt
|
|
112
|
-
homeassistant:
|
|
113
|
-
discovery:
|
|
114
|
-
prefix: homeassistant # Matches the default MQTT discovery prefix in Home Assistant
|
|
115
|
-
enabled: true
|
|
116
|
-
state_topic_suffix: state
|
|
117
|
-
docker:
|
|
118
|
-
enabled: true
|
|
119
|
-
allow_pull: true # if true, will do a `docker pull` if an update is available
|
|
120
|
-
allow_restart: true # if true, will do a `docker-compose up` if an update is installed
|
|
121
|
-
allow_build: true # if true, will do a `docker-compose build` if a git repo is configured
|
|
122
|
-
compose_version: v2 # Controls whether to use `docker-compose` (v1) or `docker compose` (v2) command
|
|
123
|
-
default_entity_picture_url: https://www.docker.com/wp-content/uploads/2022/03/Moby-logo.png # Picture for update dialog
|
|
124
|
-
device_icon: mdi:docker # Material Design Icon to use when browsing entities in Home Assistant
|
|
125
|
-
# device_icon: mdi:train-car-container # Alternative icon if you don't like Docker branding
|
|
126
|
-
discover_metadata:
|
|
127
|
-
linuxserver.io:
|
|
128
|
-
enabled: true
|
|
129
|
-
cache_ttl: 604800 # cache metadata for 1 week
|
|
130
|
-
scan_interval: 10800 # sleep interval between scan runs, in seconds
|
|
131
|
-
log:
|
|
132
|
-
level: INFO
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
### Moving Secrets Out of Config
|
|
136
|
-
|
|
137
|
-
Example use of environment variables, e.g. for secrets:
|
|
138
|
-
|
|
139
|
-
```
|
|
140
|
-
mqtt:
|
|
141
|
-
password: ${oc.env:MQTT_PASS}
|
|
142
|
-
```
|
|
143
|
-
### Customizing images and release notes
|
|
144
|
-
|
|
145
|
-
Individual docker containers can have customized entity pictures or release notes, using env variables, for example in the `docker-compose.yaml` or in a separate `.env` file:
|
|
146
|
-
|
|
147
|
-
```
|
|
148
|
-
environment:
|
|
149
|
-
- UPD2MQTT_PICTURE=https://frigate.video/images/logo.svg
|
|
150
|
-
- UPD2MQTT_RELNOTES=https://github.com/blakeblackshear/frigate/releases
|
|
69
|
+
docker run -e MQTT_USER=user1 -e MQTT_PASS=pass1 -e MQTT_HOST=192.168.1.5 ghcr.io/rhizomatics/updates2mqtt:release
|
|
151
70
|
```
|
|
152
71
|
|
|
153
|
-
The images will show up in the *Update* section of *Settings* menu in HomeAssistant,
|
|
154
|
-
as will the release notes link. SVG icons should be used.
|
|
155
|
-
|
|
156
|
-
Some popular services have the icon and release note links pre-configured, in `common_packages.yaml`,
|
|
157
|
-
and packages from `linuxserver.io` can have metadata automatically discovered.
|
|
158
|
-
|
|
159
|
-
#### Icon Sources
|
|
160
|
-
|
|
161
|
-
- [Homarr Dashboard Icons](https://github.com/homarr-labs/dashboard-icons)
|
|
162
|
-
- [Self Hosted Icons](https://github.com/selfhst/icons)
|
|
163
|
-
- [Simple Icons](https://github.com/simple-icons/simple-icons)
|
|
164
|
-
- [Tabler Icons](https://tabler.io/icons)
|
|
165
|
-
- [Papirus Icons](https://github.com/PapirusDevelopmentTeam/papirus-icon-theme)
|
|
166
|
-
- [Homelab SVG Assets](https://github.com/loganmarchione/homelab-svg-assets)
|
|
167
|
-
|
|
168
|
-
### Automated updates
|
|
169
|
-
|
|
170
|
-
If Docker containers should be immediately updated, without any confirmation
|
|
171
|
-
or trigger, *e.g.* from the HomeAssistant update dialog, then set an environment variable `UPD2MQTT_UPDATE`
|
|
172
|
-
in the target container to `Auto` ( it defaults to `Passive`)
|
|
173
|
-
|
|
174
|
-
### Custom docker builds
|
|
175
|
-
|
|
176
|
-
If the image is locally built from a checked out git repo, package update can be driven
|
|
177
|
-
by the availability of git repo changes to pull rather than a new image on a Docker registry.
|
|
178
|
-
|
|
179
|
-
Declare the git path using the env var in ``UPD2MQTT_GIT_REPO_PATH`` in the docker container ( directly or via an ``.env`` file).
|
|
180
|
-
The git repo at this path will be used as the source of timestamps, and an update command will carry out a
|
|
181
|
-
``git pull`` and ``docker-compose build`` rather than pulling an image.
|
|
182
|
-
|
|
183
|
-
Note that the updates2mqtt docker container needs access to this path declared in its volumes, and that has to
|
|
184
|
-
be read/write if automated install required.
|
|
185
|
-
|
|
186
|
-
### Environment Variables
|
|
187
|
-
|
|
188
|
-
The following environment variables can be used to configure updates2mqtt:
|
|
189
|
-
|
|
190
|
-
| Env Var | Description | Default |
|
|
191
|
-
|---------| ------------|----------|
|
|
192
|
-
| `UPD2MQTT_UPDATE` | Update mode, either `Passive` or `Auto`. If `Auto`, updates will be installed automatically. | `Passive` |
|
|
193
|
-
| `UPD2MQTT_PICTURE` | URL to an icon to use in Home Assistant. | Docker logo URL |
|
|
194
|
-
| `UPD2MQTT_RELNOTES` | URL to release notes for the package. | |
|
|
195
|
-
| `UPD2MQTT_GIT_REPO_PATH` | Relative path to a local git repo if the image is built locally. | |
|
|
196
|
-
| `UPD2MQTT_IGNORE` | If set to `True`, the container will be ignored by updates2mqtt. | False |
|
|
197
|
-
|
|
198
|
-
|
|
199
72
|
## Release Support
|
|
200
73
|
|
|
74
|
+
Presently only Docker containers are supported, although others are planned,
|
|
75
|
+
probably with priority for `apt`.
|
|
76
|
+
|
|
201
77
|
| Ecosystem | Support | Comments |
|
|
202
78
|
|-----------|-------------|----------------------------------------------------------------------------------------------------|
|
|
203
79
|
| Docker | Scan. Fetch | Fetch is ``docker pull`` only. Restart support only for ``docker-compose`` image based containers. |
|
|
@@ -234,8 +110,10 @@ interface, and the package can be remotely fetched and the component restarted.
|
|
|
234
110
|
|
|
235
111
|
## Related Projects
|
|
236
112
|
|
|
113
|
+
Other apps useful for self-hosting with the help of MQTT:
|
|
114
|
+
|
|
237
115
|
- [psmqtt](https://github.com/eschava/psmqtt) - Report system health and metrics via MQTT
|
|
238
|
-
|
|
116
|
+
|
|
239
117
|
## Development
|
|
240
118
|
|
|
241
119
|
Access to Docker APIs uses the Python [docker-py](https://docker-py.readthedocs.io/en/stable/) SDK for Python. [Eclipse Paho](https://eclipse.dev/paho/files/paho.mqtt.python/html/client.html) is used for MQTT access, and [OmegaConf](https://omegaconf.readthedocs.io) for configuration.
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
[](https://github.com/rhizomatics)
|
|
2
|
+
|
|
3
|
+
# updates2mqtt
|
|
4
|
+
|
|
5
|
+
[](https://pypi.org/project/updates2mqtt/)
|
|
6
|
+
[](https://github.com/rhizomatics/supernotify)
|
|
7
|
+
[](https://results.pre-commit.ci/latest/github/rhizomatics/updates2mqtt/main)
|
|
8
|
+
[](https://github.com/rhizomatics/updates2mqtt/actions/workflows/pypi-publish.yml)
|
|
9
|
+
[](https://github.com/rhizomatics/updates2mqtt/actions/workflows/python-package.yml)
|
|
10
|
+
[](https://github.com/rhizomatics/updates2mqtt/actions/workflows/github-code-scanning/codeql)
|
|
11
|
+
[](https://github.com/rhizomatics/updates2mqtt/actions/workflows/dependabot/dependabot-updates)
|
|
12
|
+
|
|
13
|
+
## Summary
|
|
14
|
+
|
|
15
|
+
Use Home Assistant to notify you of updates to Docker images for your containers and optionally perform the *pull* (or optionally *build*) and *update*.
|
|
16
|
+
|
|
17
|
+

|
|
18
|
+
|
|
19
|
+
## Description
|
|
20
|
+
|
|
21
|
+
updates2mqtt perioidically checks for new versions of components being available, and publishes new version info to MQTT. HomeAssistant auto discovery is supported, so all updates can be seen in the same place as Home Assistant's own components and add-ins.
|
|
22
|
+
|
|
23
|
+
Currently only Docker containers are supported, either via an image registry check, or a git repo for source (see [Local Builds](local_builds.md)). The design is modular, so other update sources can be added, at least for notification. The next anticipated is **apt** for Debian based systems.
|
|
24
|
+
|
|
25
|
+
Components can also be updated, either automatically or triggered via MQTT, for example by hitting the *Install* button in the HomeAssistant update dialog. Icons and release notes can be specified for a better HA experience.
|
|
26
|
+
|
|
27
|
+
To get started, read the [Installation](installation.md) and [Configuration](configuration.md) pages.
|
|
28
|
+
|
|
29
|
+
For a quick spin, try this:
|
|
30
|
+
|
|
31
|
+
```yaml
|
|
32
|
+
docker run -e MQTT_USER=user1 -e MQTT_PASS=pass1 -e MQTT_HOST=192.168.1.5 ghcr.io/rhizomatics/updates2mqtt:release
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Release Support
|
|
36
|
+
|
|
37
|
+
Presently only Docker containers are supported, although others are planned,
|
|
38
|
+
probably with priority for `apt`.
|
|
39
|
+
|
|
40
|
+
| Ecosystem | Support | Comments |
|
|
41
|
+
|-----------|-------------|----------------------------------------------------------------------------------------------------|
|
|
42
|
+
| Docker | Scan. Fetch | Fetch is ``docker pull`` only. Restart support only for ``docker-compose`` image based containers. |
|
|
43
|
+
|
|
44
|
+
## Healthcheck
|
|
45
|
+
|
|
46
|
+
A heartbeat JSON payload is optionally published periodically to a configurable MQTT topic, defaulting to `healthcheck/{node_name}/updates2mqtt`. It contains the current version of updates2mqtt, the node name, a timestamp, and some basic stats.
|
|
47
|
+
|
|
48
|
+
A `healthcheck.sh` script is included in the Docker image, and can be used as a Docker healthcheck, if the container environment variables are set for `MQTT_HOST`, `MQTT_PORT`, `MQTT_USER` and `MQTT_PASS`.
|
|
49
|
+
|
|
50
|
+
TIP: Check healthcheck is working using `docker inspect --format "{{json .State.Health }}" updates2mqtt | jq`
|
|
51
|
+
|
|
52
|
+
## HomeAssistant integration
|
|
53
|
+
|
|
54
|
+
Any updates that have support for automated install will automatically show in the
|
|
55
|
+
Home Assistant settings page if the [MQTT Integration](https://www.home-assistant.io/integrations/mqtt/) is installed and automatic discovery is not disabled.
|
|
56
|
+
|
|
57
|
+

|
|
58
|
+
|
|
59
|
+
The `homeassistant` default topic prefix matches the default updates2mqtt config, if its changed in HomeAssistant, then the updates2mqtt config must be changed to match.
|
|
60
|
+
|
|
61
|
+

|
|
62
|
+
|
|
63
|
+
For Home Assistant integration, updates2mqtt represents each component being managed as a [MQTT Update](https://www.home-assistant.io/integrations/update.mqtt/) entity, and uses [MQTT discovery(https://www.home-assistant.io/integrations/mqtt/#mqtt-discovery)] so that HomeAssistant automatically picks up components discovered by updates2mqtt with zero configuration on HomeAssistant itself.
|
|
64
|
+
|
|
65
|
+
There are 3 separate types of MQTT topic used for HomeAssisstant integration:
|
|
66
|
+
|
|
67
|
+
- *Config* to support auto discovery. A topic is created per component, with a name like `homeassistant/update/dockernuc_docker_jellyfin/update/config`. This can be disabled in the config file, and the `homeassistant` topic prefix can also be configured.
|
|
68
|
+
- *State* to report the current version and the latest version available, again one topic per component, like `updates2mqtt/dockernuc/docker/jellyfin`.
|
|
69
|
+
- *Command* to support triggering an update. These will be created on the fly by HomeAssistant when an update is requested, and updates2mqtt subscribes to pick up the changes, so you won't typically see these if browsing MQTT topics. Only one is needed per updates2mqtt agent, with a name like `updates2mqtt/dockernuc/docker`
|
|
70
|
+
|
|
71
|
+
If the package supports automated update, then *Skip* and *Install* buttons will appear on the Home Assistant
|
|
72
|
+
interface, and the package can be remotely fetched and the component restarted.
|
|
73
|
+
|
|
74
|
+
## Related Projects
|
|
75
|
+
|
|
76
|
+
Other apps useful for self-hosting with the help of MQTT:
|
|
77
|
+
|
|
78
|
+
- [psmqtt](https://github.com/eschava/psmqtt) - Report system health and metrics via MQTT
|
|
79
|
+
|
|
80
|
+
## Development
|
|
81
|
+
|
|
82
|
+
Access to Docker APIs uses the Python [docker-py](https://docker-py.readthedocs.io/en/stable/) SDK for Python. [Eclipse Paho](https://eclipse.dev/paho/files/paho.mqtt.python/html/client.html) is used for MQTT access, and [OmegaConf](https://omegaconf.readthedocs.io) for configuration.
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# Configuration
|
|
2
|
+
|
|
3
|
+
Create file `config.yaml` in `conf` directory. If the file is not present, a default file will be generated.
|
|
4
|
+
|
|
5
|
+
### Example configuration file
|
|
6
|
+
|
|
7
|
+
This is a maximal config file, the minimum is no config file at all, which will generate a default config file. The only mandatory values are the MQTT user name and password, everything else can be omitted.
|
|
8
|
+
|
|
9
|
+
```yaml
|
|
10
|
+
|
|
11
|
+
node:
|
|
12
|
+
name: docker-host-1 # Unique name for this instance, used to name MQTT entities. Defaults to O/S hostname
|
|
13
|
+
git_repo_path: /usr/bin/git # Path to git inside container, needed only if non-default and using local docker builds
|
|
14
|
+
healthcheck:
|
|
15
|
+
enabled: true
|
|
16
|
+
interval: 300 # publish a heartbeat every 5 minutes
|
|
17
|
+
topic_template: healthcheck/{node_name}/updates2mqtt
|
|
18
|
+
mqtt:
|
|
19
|
+
host: ${oc.env:MQTT_HOST}
|
|
20
|
+
user: ${oc.env:MQTT_USER}
|
|
21
|
+
password: ${oc.env:MQTT_PASS}$ # Use an environment variable for secrets
|
|
22
|
+
port: ${oc.env:MQTT_PORT}
|
|
23
|
+
topic_root: updates2mqtt
|
|
24
|
+
homeassistant:
|
|
25
|
+
discovery:
|
|
26
|
+
prefix: homeassistant # Matches the default MQTT discovery prefix in Home Assistant
|
|
27
|
+
enabled: true
|
|
28
|
+
state_topic_suffix: state
|
|
29
|
+
docker:
|
|
30
|
+
enabled: true
|
|
31
|
+
allow_pull: true # if true, will do a `docker pull` if an update is available
|
|
32
|
+
allow_restart: true # if true, will do a `docker-compose up` if an update is installed
|
|
33
|
+
allow_build: true # if true, will do a `docker-compose build` if a git repo is configured
|
|
34
|
+
compose_version: v2 # Controls whether to use `docker-compose` (v1) or `docker compose` (v2) command
|
|
35
|
+
default_entity_picture_url: https://www.docker.com/wp-content/uploads/2022/03/Moby-logo.png # Picture for update dialog
|
|
36
|
+
device_icon: mdi:docker # Material Design Icon to use when browsing entities in Home Assistant
|
|
37
|
+
# device_icon: mdi:train-car-container # Alternative icon if you don't like Docker branding
|
|
38
|
+
discover_metadata:
|
|
39
|
+
linuxserver.io:
|
|
40
|
+
enabled: true
|
|
41
|
+
cache_ttl: 604800 # cache metadata for 1 week
|
|
42
|
+
scan_interval: 10800 # sleep interval between scan runs, in seconds
|
|
43
|
+
log:
|
|
44
|
+
level: INFO
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Moving Secrets Out of Config
|
|
48
|
+
|
|
49
|
+
Example use of environment variables, e.g. for secrets:
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
mqtt:
|
|
53
|
+
password: ${oc.env:MQTT_PASS}
|
|
54
|
+
```
|
|
55
|
+
### Customizing images and release notes
|
|
56
|
+
|
|
57
|
+
Individual docker containers can have customized entity pictures or release notes, using env variables, for example in the `docker-compose.yaml` or in a separate `.env` file:
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
environment:
|
|
61
|
+
- UPD2MQTT_PICTURE=https://frigate.video/images/logo.svg
|
|
62
|
+
- UPD2MQTT_RELNOTES=https://github.com/blakeblackshear/frigate/releases
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
The images will show up in the *Update* section of *Settings* menu in HomeAssistant,
|
|
66
|
+
as will the release notes link. SVG icons should be used.
|
|
67
|
+
|
|
68
|
+
#### Icon Sources
|
|
69
|
+
|
|
70
|
+
Updates look nicer in Home Assistant with a suitable icon. Updates2mqtt comes
|
|
71
|
+
pre-packaged with some common ones, in `common_packages.yaml`, and can automatically fetch them (and release links) for the popular [linuxserver.io](https://www.linuxserver.io) packages.
|
|
72
|
+
|
|
73
|
+
If you have something not covered, here are some good places to look for self-hosted app icons:
|
|
74
|
+
|
|
75
|
+
- [Homarr Dashboard Icons](https://github.com/homarr-labs/dashboard-icons)
|
|
76
|
+
- [Self Hosted Icons](https://github.com/selfhst/icons)
|
|
77
|
+
- [Simple Icons](https://github.com/simple-icons/simple-icons)
|
|
78
|
+
- [Tabler Icons](https://tabler.io/icons)
|
|
79
|
+
- [Papirus Icons](https://github.com/PapirusDevelopmentTeam/papirus-icon-theme)
|
|
80
|
+
- [Homelab SVG Assets](https://github.com/loganmarchione/homelab-svg-assets)
|
|
81
|
+
|
|
82
|
+
### Automated updates
|
|
83
|
+
|
|
84
|
+
If Docker containers should be immediately updated, without any confirmation
|
|
85
|
+
or trigger, *e.g.* from the HomeAssistant update dialog, then set an environment variable `UPD2MQTT_UPDATE` in the target container to `Auto` ( it defaults to `Passive`)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
### Environment Variables
|
|
89
|
+
|
|
90
|
+
The following environment variables can be used to configure updates2mqtt:
|
|
91
|
+
|
|
92
|
+
| Env Var | Description | Default |
|
|
93
|
+
|---------| ------------|----------|
|
|
94
|
+
| `UPD2MQTT_UPDATE` | Update mode, either `Passive` or `Auto`. If `Auto`, updates will be installed automatically. | `Passive` |
|
|
95
|
+
| `UPD2MQTT_PICTURE` | URL to an icon to use in Home Assistant. | Docker logo URL |
|
|
96
|
+
| `UPD2MQTT_RELNOTES` | URL to release notes for the package. | |
|
|
97
|
+
| `UPD2MQTT_GIT_REPO_PATH` | Relative path to a local git repo if the image is built locally. | |
|
|
98
|
+
| `UPD2MQTT_IGNORE` | If set to `True`, the container will be ignored by updates2mqtt. | False |
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Installation
|
|
2
|
+
|
|
3
|
+
## Install
|
|
4
|
+
|
|
5
|
+
updates2mqtt prefers to be run inside a Docker container, though can run standalone, for example scripted via cron or systemd.
|
|
6
|
+
|
|
7
|
+
### Docker
|
|
8
|
+
|
|
9
|
+
See `examples` directory for a working `docker-compose.yaml`.
|
|
10
|
+
|
|
11
|
+
If you want to update and restart containers, then the file system paths to the location of the directory where the docker compose file lives must be available in the updates2mqtt container.
|
|
12
|
+
|
|
13
|
+
The example `docker-compose.yaml` mounts `/home/containers` for this purpose, so if your containers are in
|
|
14
|
+
`/home/containers/app1`, `/home/containers/app2` etc, then updates2mqtt will be able to find them. Map as many root paths as needed.
|
|
15
|
+
|
|
16
|
+
### Without Docker
|
|
17
|
+
|
|
18
|
+
#### Run without installing using uv
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
uv run --with updates2mqtt updates2mqtt
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
#### Install and run with pip
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
pip install updates2mqtt
|
|
28
|
+
python3 -m updates2mqtt
|
|
29
|
+
```
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Local Builds
|
|
2
|
+
|
|
3
|
+
## Custom docker builds
|
|
4
|
+
|
|
5
|
+
If the image is locally built from a checked out git repo, package update can be driven by the availability of git repo changes to pull rather than a new image on a Docker registry.
|
|
6
|
+
|
|
7
|
+
(People sometimes do this as a quick way of forking and changing a repo that doesn't quite work for them, or if the app is a development work in progress).
|
|
8
|
+
|
|
9
|
+
```yaml title="Example docker-compose.yaml snippet"
|
|
10
|
+
services:
|
|
11
|
+
mymailserver:
|
|
12
|
+
build: ./build/mymailserver
|
|
13
|
+
environment:
|
|
14
|
+
- UPD2MQTT_GIT_REPO_PATH=build/mymailserver
|
|
15
|
+
volumes:
|
|
16
|
+
- /home/containers/mymailserver/build:/home/containers/mymailserver/build
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Declare the git path using the env var in ``UPD2MQTT_GIT_REPO_PATH`` in the docker container ( directly or via an ``.env`` file). The git repo at this path will be used as the source of timestamps, and an update command will carry out a
|
|
20
|
+
``git pull`` and ``docker-compose build`` rather than pulling an image.
|
|
21
|
+
|
|
22
|
+
Note that the updates2mqtt docker container needs access to this path declared in its volumes, and that has to be read/write if automated install required.
|
|
@@ -9,9 +9,9 @@ node:
|
|
|
9
9
|
topic_template: healthcheck/{node_name}/updates2mqtt
|
|
10
10
|
mqtt:
|
|
11
11
|
host: localhost
|
|
12
|
-
port:
|
|
13
|
-
user:
|
|
14
|
-
password:
|
|
12
|
+
port: 1883
|
|
13
|
+
user: mymqttuser
|
|
14
|
+
password: mysecret
|
|
15
15
|
topic_root: updates2mqtt
|
|
16
16
|
homeassistant:
|
|
17
17
|
discovery:
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
log:
|
|
2
|
+
level: INFO
|
|
3
|
+
node:
|
|
4
|
+
name: Jeys-MacBook-Pro
|
|
5
|
+
git_path: /usr/bin/git
|
|
6
|
+
healthcheck:
|
|
7
|
+
enabled: true
|
|
8
|
+
interval: 300
|
|
9
|
+
topic_template: healthcheck/{node_name}/updates2mqtt
|
|
10
|
+
mqtt:
|
|
11
|
+
host: ${oc.env:MQTT_HOST,localhost}
|
|
12
|
+
user: ${oc.env:MQTT_USER,null}
|
|
13
|
+
password: ${oc.env:MQTT_PASS,null}
|
|
14
|
+
port: ${oc.decode:${oc.env:MQTT_PORT,1883}}
|
|
15
|
+
topic_root: updates2mqtt
|
|
16
|
+
homeassistant:
|
|
17
|
+
discovery:
|
|
18
|
+
prefix: homeassistant
|
|
19
|
+
enabled: true
|
|
20
|
+
state_topic_suffix: state
|
|
21
|
+
docker:
|
|
22
|
+
enabled: true
|
|
23
|
+
allow_pull: true
|
|
24
|
+
allow_restart: true
|
|
25
|
+
allow_build: true
|
|
26
|
+
compose_version: v2
|
|
27
|
+
default_entity_picture_url: https://www.docker.com/wp-content/uploads/2022/03/Moby-logo.png
|
|
28
|
+
device_icon: mdi:docker
|
|
29
|
+
discover_metadata:
|
|
30
|
+
linuxserver.io:
|
|
31
|
+
enabled: true
|
|
32
|
+
cache_ttl: 604800
|
|
33
|
+
scan_interval: 10800
|
|
@@ -7,7 +7,7 @@ authors = [
|
|
|
7
7
|
]
|
|
8
8
|
|
|
9
9
|
requires-python = ">=3.13"
|
|
10
|
-
version = "1.3.
|
|
10
|
+
version = "1.3.7"
|
|
11
11
|
license="Apache-2.0"
|
|
12
12
|
keywords=["mqtt", "docker", "updates", "automation","home-assistant","homeassistant","selfhosting"]
|
|
13
13
|
|
|
@@ -47,14 +47,14 @@ managed = true
|
|
|
47
47
|
[dependency-groups]
|
|
48
48
|
dev = [
|
|
49
49
|
"ruff>=0.13.0",
|
|
50
|
-
"pre-commit>=
|
|
50
|
+
"pre-commit>=4.4.0",
|
|
51
51
|
"pytest>=8.4.2",
|
|
52
52
|
"pytest-mock>=3.15.0",
|
|
53
53
|
"pytest-asyncio>=1.2.0",
|
|
54
54
|
"pytest-cov>=7.0.0",
|
|
55
55
|
"pytest-httpx",
|
|
56
56
|
"pytest-mqtt>=0.6.0",
|
|
57
|
-
"pytest-subprocess>=1.5.
|
|
57
|
+
"pytest-subprocess>=1.5.3",
|
|
58
58
|
"coverage",
|
|
59
59
|
]
|
|
60
60
|
mkdocs=[
|
|
@@ -171,6 +171,8 @@ directory="htmlcov"
|
|
|
171
171
|
mypy_path=["./src","./tests"]
|
|
172
172
|
|
|
173
173
|
[project.urls]
|
|
174
|
+
Homepage="https://updates2mqtt.rhizomatics.org.uk"
|
|
174
175
|
Repository="https://github.com/rhizomatics/updates2mqtt"
|
|
175
176
|
Documentation="https://updates2mqtt.rhizomatics.org.uk"
|
|
176
|
-
Issues="https://github.com/rhizomatics/updates2mqtt/issues"
|
|
177
|
+
Issues="https://github.com/rhizomatics/updates2mqtt/issues"
|
|
178
|
+
Changelog="https://github.com/rhizomatics/updates2mqtt/blob/main/CHANGELOG.md"
|
|
@@ -99,12 +99,17 @@ class App:
|
|
|
99
99
|
for scanner in self.scanners:
|
|
100
100
|
self.publisher.subscribe_hass_command(scanner)
|
|
101
101
|
|
|
102
|
-
while not self.stopped.is_set():
|
|
102
|
+
while not self.stopped.is_set() and self.publisher.is_available():
|
|
103
103
|
await self.scan()
|
|
104
|
-
if not self.stopped.is_set():
|
|
104
|
+
if not self.stopped.is_set() and self.publisher.is_available():
|
|
105
105
|
await asyncio.sleep(self.cfg.scan_interval)
|
|
106
106
|
else:
|
|
107
107
|
log.info("Stop requested, exiting run loop and skipping sleep")
|
|
108
|
+
|
|
109
|
+
if not self.publisher.is_available():
|
|
110
|
+
log.error("MQTT fatal connection error - check host,port,user,password in config")
|
|
111
|
+
self.shutdown(exit_code=1)
|
|
112
|
+
|
|
108
113
|
log.debug("Exiting run loop")
|
|
109
114
|
|
|
110
115
|
async def on_discovery(self, discovery: Discovery) -> None:
|
|
@@ -144,8 +149,8 @@ class App:
|
|
|
144
149
|
await asyncio.gather(*running_tasks, return_exceptions=True)
|
|
145
150
|
log.debug("Cancellation task completed")
|
|
146
151
|
|
|
147
|
-
def shutdown(self, *args) -> None: # noqa: ANN002
|
|
148
|
-
log.info("Shutting down
|
|
152
|
+
def shutdown(self, *args, exit_code: int = 143) -> None: # noqa: ANN002, ARG002
|
|
153
|
+
log.info("Shutting down, exit_code: %s", exit_code)
|
|
149
154
|
self.stopped.set()
|
|
150
155
|
for scanner in self.scanners:
|
|
151
156
|
scanner.stop()
|
|
@@ -155,8 +160,11 @@ class App:
|
|
|
155
160
|
self.publisher.stop()
|
|
156
161
|
log.debug("Interrupt: %s", interrupt_task.done())
|
|
157
162
|
log.info("Shutdown handling complete")
|
|
163
|
+
sys.exit(exit_code) # SIGTERM Graceful Exit = 143
|
|
158
164
|
|
|
159
165
|
async def healthcheck(self) -> None:
|
|
166
|
+
if not self.publisher.is_available():
|
|
167
|
+
return
|
|
160
168
|
self.publisher.publish(
|
|
161
169
|
topic=self.healthcheck_topic,
|
|
162
170
|
payload={
|
|
@@ -178,7 +186,7 @@ async def repeated_call(func: Callable, interval: int = 60, *args: Any, **kwargs
|
|
|
178
186
|
await func(*args, **kwargs)
|
|
179
187
|
await asyncio.sleep(interval)
|
|
180
188
|
except asyncio.CancelledError:
|
|
181
|
-
log.
|
|
189
|
+
log.debug("Periodic task cancelled")
|
|
182
190
|
except Exception:
|
|
183
191
|
log.exception("Periodic task failed")
|
|
184
192
|
|