Versions
- pm_auto: 1.2.12
- pironman5: 1.2.22 (parent service)
- Raspberry Pi 5 (16 GB), Debian Trixie, Python 3.13
Symptom
With default oled_network_interface: "all", on a host where the set of
network interfaces changes frequently (e.g. Docker bridges coming up and
down when stacks are recreated), the OLED render loop raises
IndexError: list index out of range once per second:
File "/.../pm_auto/oled.py", line 172, in draw_oled
ip = ips[self.ip_index]
~~~^^^^^^^^^^^^^^^
IndexError: list index out of range
The service stays alive (the @log_error decorator swallows the
exception), but the journal fills with tracebacks and the OLED frame
that renders the IP stops updating.
Root cause
In draw_oled, after rendering one frame, the index is bumped:
self.ip_index = (self.ip_index + 1) % len(ips)
…using len(ips) as it was during this call. On the next call,
get_data may return a shorter data['ips'] (an interface disappeared
between calls), so self.ip_index can be >= len(ips). The subsequent
ips[self.ip_index] then raises.
This is easy to trigger on a host with many short-lived bridges
(typical Docker setup with several compose stacks).
Reproduction
oled_network_interface: "all" (default).
- On the host, repeatedly recreate Docker stacks so the bridge count
fluctuates (e.g. docker compose down && up -d on a few stacks).
journalctl -u pironman5 -f shows the traceback every 1 s.
Suggested fix
Clamp self.ip_index against the current list size before indexing:
ips = data['ips']
ip = 'DISCONNECTED'
if len(ips) > 0:
if self.ip_index >= len(ips):
self.ip_index = 0
ip = ips[self.ip_index]
if time.time() - self.ip_show_next_timestamp > self.ip_show_next_interval:
self.ip_show_next_timestamp = time.time()
self.ip_index = (self.ip_index + 1) % len(ips)
Workaround
Setting oled_network_interface to a specific, stable interface
("eth0" in my case) sidesteps the issue.
Related
#2 (filtering out virtual interface prefixes) would reduce how often
the list size changes, but doesn't fully prevent the crash: any
transient interface that isn't in the prefix list (or any future
interface change) would still trigger the same IndexError. The two
fixes are complementary.
Versions
Symptom
With default
oled_network_interface: "all", on a host where the set ofnetwork interfaces changes frequently (e.g. Docker bridges coming up and
down when stacks are recreated), the OLED render loop raises
IndexError: list index out of rangeonce per second:The service stays alive (the
@log_errordecorator swallows theexception), but the journal fills with tracebacks and the OLED frame
that renders the IP stops updating.
Root cause
In
draw_oled, after rendering one frame, the index is bumped:…using
len(ips)as it was during this call. On the next call,get_datamay return a shorterdata['ips'](an interface disappearedbetween calls), so
self.ip_indexcan be>= len(ips). The subsequentips[self.ip_index]then raises.This is easy to trigger on a host with many short-lived bridges
(typical Docker setup with several compose stacks).
Reproduction
oled_network_interface: "all"(default).fluctuates (e.g.
docker compose down && up -don a few stacks).journalctl -u pironman5 -fshows the traceback every 1 s.Suggested fix
Clamp
self.ip_indexagainst the current list size before indexing:Workaround
Setting
oled_network_interfaceto a specific, stable interface(
"eth0"in my case) sidesteps the issue.Related
#2 (filtering out virtual interface prefixes) would reduce how often
the list size changes, but doesn't fully prevent the crash: any
transient interface that isn't in the prefix list (or any future
interface change) would still trigger the same
IndexError. The twofixes are complementary.