mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-11-02 10:52:22 +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}
|
for a in interface.get('addr_info', []) if 'local' in a}
|
||||||
except (ValueError, TypeError, KeyError) as exc:
|
except (ValueError, TypeError, KeyError) as exc:
|
||||||
raise IconError('host address check unavailable') from 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]
|
addresses = [ip for ip in addresses if ip not in host_ips]
|
||||||
if not addresses:
|
if not addresses:
|
||||||
raise IconError('container has no isolated private address')
|
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.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'))
|
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):
|
def test_address_change_or_stop_during_request_cannot_cache(self):
|
||||||
for second in ['http://10.0.0.43:8080', icons.IconError('stopped')]:
|
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:
|
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