diff --git a/roles/homeassistant/files/99-homeassistant.rules b/roles/homeassistant/files/99-homeassistant.rules index 42b1684..04728a9 100644 --- a/roles/homeassistant/files/99-homeassistant.rules +++ b/roles/homeassistant/files/99-homeassistant.rules @@ -1 +1 @@ -SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", MODE="0660", GROUP="ha" +SUBSYSTEM=="tty", ATTRS{idVendor}=="10c4", ATTRS{idProduct}=="ea60", MODE="0660", GROUP="homeassistant" diff --git a/roles/homeassistant/files/homeassistant-docker-venv.patch b/roles/homeassistant/files/homeassistant-docker-venv.patch new file mode 100644 index 0000000..60eac58 --- /dev/null +++ b/roles/homeassistant/files/homeassistant-docker-venv.patch @@ -0,0 +1,139 @@ +--- run.orig 2025-01-28 08:45:53.981024625 +0000 ++++ run 2025-01-28 08:45:38.177986885 +0000 +@@ -21,49 +21,52 @@ + # Create user + # + +-# Some HA commands seem to fail if we don't have an actual user. +-# ie: shell_command would return error code 255 +-bashio::log.info "Creating user $USER with $PUID:$PGID" +- +-deluser "$USER" >/dev/null 2>&1 || true +-delgroup "$GROUP" >/dev/null 2>&1 || true +- +-# Re-use existing group (can't delgroup a group that is in use) +-group="$(getent group "$PGID" | cut -d: -f1 || true)" +-if [ -z "$group" ]; then +- addgroup -g "$PGID" "$GROUP" +-else +- bashio::log.notice "Re-using existing group with gid $PGID: $group" +- GROUP="$group" +-fi +- +-# Replace existing user (ensures correct shell and primary group) +-user="$(getent passwd "$PUID" | cut -d: -f1 || true)" +-if [ -n "$user" ]; then +- bashio::log.notice "Replacing existing user with uid $PUID: $user" +- deluser "$user" +-fi +-adduser -G "$GROUP" -D -u "$PUID" "$USER" ++if [ "$(whoami)" != "homeassistant" ]; then + +-if [ -n "${EXTRA_GID:-}" ]; then +- bashio::log.info "Resolving supplementary GIDs: $EXTRA_GID" +- supplementary_groups=() +- +- for gid in $EXTRA_GID; do +- group="$(getent group "$gid" | cut -d: -f1 || true)" +- +- if [ -z "$group" ]; then +- group="$USER-$gid" +- addgroup -g "$gid" "$group" +- fi ++ # Some HA commands seem to fail if we don't have an actual user. ++ # ie: shell_command would return error code 255 ++ bashio::log.info "Creating user $USER with $PUID:$PGID" ++ ++ deluser "$USER" >/dev/null 2>&1 || true ++ delgroup "$GROUP" >/dev/null 2>&1 || true ++ ++ # Re-use existing group (can't delgroup a group that is in use) ++ group="$(getent group "$PGID" | cut -d: -f1 || true)" ++ if [ -z "$group" ]; then ++ addgroup -g "$PGID" "$GROUP" ++ else ++ bashio::log.notice "Re-using existing group with gid $PGID: $group" ++ GROUP="$group" ++ fi + +- supplementary_groups+=( "$group" ) +- done ++ # Replace existing user (ensures correct shell and primary group) ++ user="$(getent passwd "$PUID" | cut -d: -f1 || true)" ++ if [ -n "$user" ]; then ++ bashio::log.notice "Replacing existing user with uid $PUID: $user" ++ deluser "$user" ++ fi ++ adduser -G "$GROUP" -D -u "$PUID" "$USER" + +- bashio::log.info "Appending supplementary groups: ${supplementary_groups[*]}" +- for group in "${supplementary_groups[@]}"; do +- addgroup "$USER" "$group" +- done ++ if [ -n "${EXTRA_GID:-}" ]; then ++ bashio::log.info "Resolving supplementary GIDs: $EXTRA_GID" ++ supplementary_groups=() ++ ++ for gid in $EXTRA_GID; do ++ group="$(getent group "$gid" | cut -d: -f1 || true)" ++ ++ if [ -z "$group" ]; then ++ group="$USER-$gid" ++ addgroup -g "$gid" "$group" ++ fi ++ ++ supplementary_groups+=( "$group" ) ++ done ++ ++ bashio::log.info "Appending supplementary groups: ${supplementary_groups[*]}" ++ for group in "${supplementary_groups[@]}"; do ++ addgroup "$USER" "$group" ++ done ++ fi + fi + + # +@@ -82,8 +85,12 @@ + # + + bashio::log.info "Initializing venv in $VENV_PATH" +-su "$USER" \ +- -c "python3 -m venv --system-site-packages '$VENV_PATH'" ++if [ "$(whoami)" = "homeassistant" ]; then ++ python3 -m venv --system-site-package "$VENV_PATH" ++else ++ su "$USER" \ ++ -c "python3 -m venv --system-site-packages '$VENV_PATH'" ++fi + + # + # Fix permissions +@@ -104,8 +111,12 @@ + export UV_SYSTEM_PYTHON=false + + bashio::log.info "Installing uv into venv" +-uv --version && su "$USER" \ +- -c "uv pip freeze --system|grep ^uv=|xargs uv pip install" ++if [ "$(whoami)" = "homeassistant" ]; then ++ uv --version && uv pip freeze --system|grep ^uv=|xargs uv pip install ++else ++ uv --version && su "$USER" \ ++ -c "uv pip freeze --system|grep ^uv=|xargs uv pip install" ++fi + + bashio::log.info "Setting new \$HOME" + HOME="$( getent passwd "$USER" | cut -d: -f6 )" +@@ -122,6 +133,10 @@ + fi + + bashio::log.info "Starting homeassistant" +-exec \ +- s6-setuidgid "$USER" \ +- python3 -m homeassistant --config "$CONFIG_PATH" ++if [ "$(whoami)" = "homeassistant" ]; then ++ exec python3 -m homeassistant --config "$CONFIG_PATH" ++else ++ exec \ ++ s6-setuidgid "$USER" \ ++ python3 -m homeassistant --config "$CONFIG_PATH" ++fi diff --git a/roles/homeassistant/tasks/main.yml b/roles/homeassistant/tasks/main.yml index c11dfcb..ab6bc4f 100644 --- a/roles/homeassistant/tasks/main.yml +++ b/roles/homeassistant/tasks/main.yml @@ -1,13 +1,13 @@ --- - name: Create group ansible.builtin.group: - name: ha + name: homeassistant - name: Create user ansible.builtin.user: - name: ha + name: homeassistant comment: Podman HomeAssistant - group: ha + group: homeassistant shell: /sbin/nologin - name: Enable user lingering @@ -15,8 +15,8 @@ argv: - loginctl - enable-linger - - ha - creates: /var/lib/systemd/linger/ha + - homeassistant + creates: /var/lib/systemd/linger/homeassistant - name: Install dependencies ansible.builtin.package: @@ -25,6 +25,46 @@ with_items: - bluez - git + - patch + +- name: Get venv support for container + ansible.builtin.git: + dest: /usr/local/src/homeassistant-docker-venv + repo: https://github.com/tribut/homeassistant-docker-venv.git + update: true + version: master + register: git_result + +- name: Create venv support directory + ansible.builtin.file: + path: /usr/local/libexec/homeassistant-docker-venv + state: directory + mode: "0755" + owner: root + group: "{{ ansible_wheel }}" + +- name: Check if venv support script exists + ansible.builtin.stat: + path: /usr/local/libexec/homeassistant-docker-venv/run + changed_when: false + register: stat_result + +- name: Copy venv support script + ansible.builtin.copy: + dest: /usr/local/libexec/homeassistant-docker-venv/run + src: /usr/local/src/homeassistant-docker-venv/run + mode: "0755" + owner: root + group: "{{ ansible_wheel }}" + remote_src: true + when: not stat_result.stat.exists or git_result.changed + +# https://github.com/home-assistant/core/issues/128214 +- name: Patch venv support script + ansible.posix.patch: + dest: /usr/local/libexec/homeassistant-docker-venv/run + src: homeassistant-docker-venv.patch + notify: Restart homeassistant - name: Enable bluetooth services ansible.builtin.service: @@ -69,7 +109,7 @@ state: true persistent: true -- name: Allow ha to connect specific devices +- name: Allow homeassistant to connect specific devices ansible.builtin.copy: dest: /etc/udev/rules.d/99-homeassistant.rules src: 99-homeassistant.rules @@ -83,8 +123,8 @@ path: /export/homeassistant state: directory mode: "0700" - owner: ha - group: ha + owner: homeassistant + group: homeassistant setype: _default - name: Link config directory diff --git a/roles/homeassistant/templates/homeassistant-container.service.j2 b/roles/homeassistant/templates/homeassistant-container.service.j2 index 9f14fa7..a22c105 100644 --- a/roles/homeassistant/templates/homeassistant-container.service.j2 +++ b/roles/homeassistant/templates/homeassistant-container.service.j2 @@ -4,15 +4,19 @@ Wants=network-online.target After=network-online.target [Service] -User=ha +User=homeassistant ExecStart=/usr/bin/podman run \ --rm -p 127.0.0.1:8008:8123 \ --name homeassistant \ + --env PGID=1000 \ + --env PUID=1000 \ --env TZ=Europe/Helsinki \ + --env UMASK=007 \ --userns keep-id \ --device /dev/ttyUSB0 \ --volume /run/dbus:/run/dbus:ro \ --volume /srv/homeassistant:/config:rw \ + --volume /usr/local/libexec/homeassistant-docker-venv/run:/etc/services.d/home-assistant/run:ro \ docker.io/homeassistant/home-assistant:{{ homeassistant_version }} ExecStop=/usr/bin/podman stop --ignore homeassistant ExecStopPost=/usr/bin/podman rm -f --ignore homeassistant