diff --git a/pkgs/additional/sane-scripts/src/sane-ip-check b/pkgs/additional/sane-scripts/src/sane-ip-check index a220e30ac..8de68c02e 100755 --- a/pkgs/additional/sane-scripts/src/sane-ip-check +++ b/pkgs/additional/sane-scripts/src/sane-ip-check @@ -14,11 +14,16 @@ import logging import requests import subprocess import sys +import time from sane_ssdp import get_any_wan logger = logging.getLogger(__name__) +# retry on failure to get IP address until this much time has elapsed. +# not a strict deadline/timeout +MAX_DURATION = 45.0 + def get_wan_fallback(): "untrusted method in which to get the WAN IP" r = requests.get("https://ipinfo.io/ip") @@ -29,13 +34,28 @@ def get_wan_fallback(): else: return ip -def main(format: str, try_upnp: bool, expect: str|None) -> None: +def try_get_once(try_upnp: bool) -> tuple[str|None, str]: upnp_details = get_any_wan() if try_upnp else None if upnp_details: root_dev, _lan_ip, wan_ip = upnp_details else: root_dev, wan_ip = "", get_wan_fallback() + return root_dev, wan_ip + +def get_fault_tolerant(try_upnp: bool) -> tuple[str|None, str]: + start = time.time() + while True: + try: + return try_get_once(try_upnp) + except Exception as e: + logger.warn(e) + if time.time() - start > MAX_DURATION: + raise + +def main(format: str, try_upnp: bool, expect: str|None) -> None: + root_dev, wan_ip = get_fault_tolerant(try_upnp) + if expect: assert wan_ip == expect, f"actual IP {wan_ip} != expected IP {expect}"