mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2025-01-31 16:36:20 +00:00
fix iputil so that it doesn't launch dozens of processes when you give it a full path and so that it tries executables in preference order and stops as soon as one gives out a dotted-quad string
This commit is contained in:
parent
e274f4350c
commit
9b08691f51
@ -4,7 +4,7 @@
|
||||
# most recent version authored by Zooko O'Whielacronx, working for Allmydata
|
||||
|
||||
# from the Python Standard Library
|
||||
import re, socket, sys
|
||||
import os, re, socket, sys
|
||||
|
||||
# from Twisted
|
||||
from twisted.internet import defer
|
||||
@ -13,6 +13,9 @@ from twisted.internet.protocol import DatagramProtocol
|
||||
from twisted.internet.utils import getProcessOutput
|
||||
from twisted.python.procutils import which
|
||||
|
||||
# from allmydata.util
|
||||
import observer
|
||||
|
||||
def get_local_addresses_async(target='A.ROOT-SERVERS.NET'):
|
||||
"""
|
||||
Return a Deferred that fires with a list of IPv4 addresses (as dotted-quad
|
||||
@ -46,7 +49,7 @@ def get_local_addresses_async(target='A.ROOT-SERVERS.NET'):
|
||||
def get_local_ip_for(target):
|
||||
"""Find out what our IP address is for use by a given target.
|
||||
|
||||
@returns:the IP address as a dotted-quad string which could be used by
|
||||
@return: the IP address as a dotted-quad string which could be used by
|
||||
to connect to us. It might work for them, it might not. If
|
||||
there is no suitable address (perhaps we don't currently have an
|
||||
externally-visible interface), this will return None.
|
||||
@ -112,6 +115,40 @@ _irix_path = '/usr/etc/ifconfig'
|
||||
# Solaris 2.x
|
||||
_sunos_path = '/usr/sbin/ifconfig'
|
||||
|
||||
class SequentialTrier(object):
|
||||
""" I hold a list of executables to try and try each one in turn
|
||||
until one gives me a list of IP addresses."""
|
||||
|
||||
def __init__(self, exebasename, args, regex):
|
||||
assert not os.path.isabs(exebasename)
|
||||
self.exes_left_to_try = which(exebasename)
|
||||
self.exes_left_to_try.reverse()
|
||||
self.args = args
|
||||
self.regex = regex
|
||||
self.o = observer.OneShotObserverList()
|
||||
self._try_next()
|
||||
|
||||
def _try_next(self):
|
||||
if not self.exes_left_to_try:
|
||||
self.o.fire(None)
|
||||
else:
|
||||
exe = self.exes_left_to_try.pop()
|
||||
d2 = _query(exe, self.args, self.regex)
|
||||
|
||||
def cb(res):
|
||||
if res:
|
||||
self.o.fire(res)
|
||||
else:
|
||||
self._try_next()
|
||||
|
||||
def eb(why):
|
||||
self._try_next()
|
||||
|
||||
d2.addCallbacks(cb, eb)
|
||||
|
||||
def when_tried(self):
|
||||
return self.o.when_fired()
|
||||
|
||||
# k: platform string as provided in the value of _platform_map
|
||||
# v: tuple of (path_to_tool, args, regex,)
|
||||
_tool_map = {
|
||||
@ -131,20 +168,15 @@ def _find_addresses_via_config():
|
||||
|
||||
(pathtotool, args, regex,) = _tool_map[platform]
|
||||
|
||||
l = []
|
||||
for executable in which(pathtotool):
|
||||
l.append(_query(executable, args, regex))
|
||||
dl = defer.DeferredList(l)
|
||||
def _gather_results(res):
|
||||
addresses = []
|
||||
for (succ, addrs,) in res:
|
||||
if succ:
|
||||
for addr in addrs:
|
||||
if addr not in addresses:
|
||||
addresses.append(addr)
|
||||
return addresses
|
||||
dl.addCallback(_gather_results)
|
||||
return dl
|
||||
# If pathtotool is a fully qualified path then we just try that.
|
||||
# If it is merely an executable name then we use Twisted's
|
||||
# "which()" utility and try each executable in turn until one
|
||||
# gives us something that resembles a dotted-quad IPv4 address.
|
||||
|
||||
if os.path.isabs(pathtotool):
|
||||
return _query(pathtotool, args, regex)
|
||||
else:
|
||||
return SequentialTrier(pathtotool, args, regex).when_tried()
|
||||
|
||||
def _query(path, args, regex):
|
||||
d = getProcessOutput(path, args)
|
||||
|
Loading…
x
Reference in New Issue
Block a user