mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-11-01 10:22:08 +00:00
fix: preserve runtime address order for local icon lookup
This commit is contained in:
@@ -94,7 +94,11 @@ def _origin(vmid, payload):
|
||||
for a in interface.get('addr_info', []) if 'local' in a}
|
||||
except (ValueError, TypeError, KeyError) as exc:
|
||||
raise IconError('host address check unavailable') from exc
|
||||
addresses = sorted({str(ipaddress.ip_address(ip)) for ip in ips if _private_ip(ip)}, key=lambda ip: ':' in ip)
|
||||
# Preserve lxc-info's reported order (CT215: eth0 then Docker bridges).
|
||||
# Unordered set iteration selected an internal bridge at random. Keep
|
||||
# runtime order within each address family, including when deduplicating.
|
||||
addresses = list(dict.fromkeys(str(ipaddress.ip_address(ip)) for ip in ips if _private_ip(ip)))
|
||||
addresses.sort(key=lambda ip: ':' in ip)
|
||||
addresses = [ip for ip in addresses if ip not in host_ips]
|
||||
if not addresses:
|
||||
raise IconError('container has no isolated private address')
|
||||
|
||||
@@ -145,6 +145,18 @@ class Icons(unittest.TestCase):
|
||||
self.assertTrue(icons._same_origin('https://10.0.0.42:443', 'https://10.0.0.42/icon'))
|
||||
self.assertFalse(icons._same_origin('https://10.0.0.42', 'https://user@10.0.0.42/icon'))
|
||||
|
||||
def test_multiple_private_addresses_retain_runtime_order_not_set_order(self):
|
||||
# Real CT215 lxc-info: eth0 followed by three Docker bridges and ULA.
|
||||
observed = ['10.0.0.27', '172.17.0.1', '172.18.0.1', '172.19.0.1',
|
||||
'fd40:359f:8a1b:f9b3:be24:11ff:fe85:bd05']
|
||||
for addresses in (observed, list(reversed(observed))):
|
||||
expected = next(ip for ip in addresses if ':' not in ip)
|
||||
def resolve(args):
|
||||
return '\n'.join(addresses + addresses) if args[0] == 'lxc-info' else self.resolve(args)
|
||||
with patch.object(icons, '_run', side_effect=resolve), patch.object(icons, '_worker', return_value=(self.png, 'image/png')) as worker:
|
||||
icons.discover(101, self.payload)
|
||||
worker.assert_called_once_with(f'http://{expected}:8080')
|
||||
|
||||
def test_address_change_or_stop_during_request_cannot_cache(self):
|
||||
for second in ['http://10.0.0.43:8080', icons.IconError('stopped')]:
|
||||
with patch.object(icons, '_origin', side_effect=['http://10.0.0.42:8080', second]), patch.object(icons, '_worker', return_value=(self.png, 'image/png')), patch.object(icons, 'store') as store:
|
||||
|
||||
Reference in New Issue
Block a user