|
|
|
@@ -34,17 +34,42 @@
|
|
|
|
|
# stopped and masked rather than merely disabled -- masked so a stray
|
|
|
|
|
# `systemctl start` or a leftover dependency cannot bring them back alongside
|
|
|
|
|
# the containers.
|
|
|
|
|
- name: Stop and mask the native CAN services
|
|
|
|
|
ansible.builtin.systemd:
|
|
|
|
|
name: "{{ item }}"
|
|
|
|
|
state: stopped
|
|
|
|
|
enabled: false
|
|
|
|
|
masked: true
|
|
|
|
|
- name: Find which native CAN units still exist
|
|
|
|
|
ansible.builtin.stat:
|
|
|
|
|
path: "/etc/systemd/system/{{ item }}.service"
|
|
|
|
|
loop:
|
|
|
|
|
- open3e
|
|
|
|
|
- e3oncan
|
|
|
|
|
failed_when: false
|
|
|
|
|
register: heating_can_native_units
|
|
|
|
|
|
|
|
|
|
# Stop and disable BEFORE anything else, and do NOT swallow the result.
|
|
|
|
|
#
|
|
|
|
|
# The first version did stop + disable + mask in one call with
|
|
|
|
|
# failed_when: false, then deleted the unit files. Masking a unit whose file
|
|
|
|
|
# still exists conflicts, so the call failed, failed_when hid it, nothing was
|
|
|
|
|
# stopped -- and the next task deleted the unit files out from under two
|
|
|
|
|
# running processes. systemctl is-enabled then reported "not-found" and looked
|
|
|
|
|
# clean while is-active still said "active".
|
|
|
|
|
#
|
|
|
|
|
# The result on 2026-08-10 was two open3e instances issuing UDS requests on the
|
|
|
|
|
# same CAN bus for nine minutes, fighting over the open3e-edge client ID and
|
|
|
|
|
# kicking each other off the broker.
|
|
|
|
|
#
|
|
|
|
|
# Only units that actually exist are touched, so a fresh host does not need an
|
|
|
|
|
# error swallowed to get through this.
|
|
|
|
|
- name: Stop and disable the native CAN services
|
|
|
|
|
ansible.builtin.systemd:
|
|
|
|
|
name: "{{ item.item }}"
|
|
|
|
|
state: stopped
|
|
|
|
|
enabled: false
|
|
|
|
|
loop: "{{ heating_can_native_units.results }}"
|
|
|
|
|
loop_control:
|
|
|
|
|
label: "{{ item.item }}"
|
|
|
|
|
when: item.stat.exists
|
|
|
|
|
|
|
|
|
|
# Masking is deliberately NOT used. It writes a symlink at the same path the
|
|
|
|
|
# next task removes, so the two cancel out -- which is half of how the original
|
|
|
|
|
# failed. With the unit files gone there is nothing left to start.
|
|
|
|
|
- name: Remove the native unit files
|
|
|
|
|
ansible.builtin.file:
|
|
|
|
|
path: "/etc/systemd/system/{{ item }}.service"
|
|
|
|
@@ -54,10 +79,30 @@
|
|
|
|
|
- e3oncan
|
|
|
|
|
notify: Reload systemd
|
|
|
|
|
|
|
|
|
|
# The venvs are the point of this change -- leaving them would leave the thing
|
|
|
|
|
# that churned. Their configuration is NOT removed: devices.json, the overlay
|
|
|
|
|
# and the env file are still rendered below and bind-mounted into the
|
|
|
|
|
# containers.
|
|
|
|
|
# The invariant that actually matters is "no native process is on the CAN bus",
|
|
|
|
|
# and systemd reporting success is not the same claim. Two open3e instances
|
|
|
|
|
# polling one bus is the failure this whole block exists to prevent, so it is
|
|
|
|
|
# asserted directly rather than inferred from the calls above.
|
|
|
|
|
- name: Check for surviving native CAN processes
|
|
|
|
|
ansible.builtin.command:
|
|
|
|
|
argv: [pgrep, -af, "edge-host/(open3e|e3oncan)"]
|
|
|
|
|
register: heating_can_survivors
|
|
|
|
|
changed_when: false
|
|
|
|
|
failed_when: false
|
|
|
|
|
|
|
|
|
|
- name: Assert no native CAN process survived
|
|
|
|
|
ansible.builtin.assert:
|
|
|
|
|
that:
|
|
|
|
|
- heating_can_survivors.stdout | default('') | length == 0
|
|
|
|
|
fail_msg: >-
|
|
|
|
|
A native open3e/e3oncan process is still running after the units were
|
|
|
|
|
stopped and removed:
|
|
|
|
|
{{ heating_can_survivors.stdout_lines | default([]) | join('; ') }}.
|
|
|
|
|
Starting the container now would put two readers on the same CAN bus --
|
|
|
|
|
two open3e instances issue competing UDS requests and take over each
|
|
|
|
|
other's MQTT session. Kill the survivors, then re-run.
|
|
|
|
|
success_msg: No native CAN processes remain; safe to start the container.
|
|
|
|
|
|
|
|
|
|
- name: Remove the native venvs
|
|
|
|
|
ansible.builtin.file:
|
|
|
|
|
path: "{{ item }}"
|
|
|
|
|