Adds workaround for routing 169.254.x.x addresses
See: https://bugs.launchpad.net/quantum/+bug/1174657
This commit is contained in:
parent
dcafa75141
commit
4b08f9ef93
@ -16,10 +16,12 @@
|
||||
|
||||
import posixpath
|
||||
import urllib2
|
||||
import urlparse
|
||||
|
||||
from cloudbaseinit.metadata.services import base
|
||||
from cloudbaseinit.openstack.common import cfg
|
||||
from cloudbaseinit.openstack.common import log as logging
|
||||
from cloudbaseinit.osutils import factory as osutils_factory
|
||||
|
||||
opts = [
|
||||
cfg.StrOpt('metadata_base_url', default='http://169.254.169.254/',
|
||||
@ -37,8 +39,38 @@ class HttpService(base.BaseMetadataService):
|
||||
super(HttpService, self).__init__()
|
||||
self._enable_retry = True
|
||||
|
||||
def _check_metadata_ip_route(self):
|
||||
'''
|
||||
Workaround for: https://bugs.launchpad.net/quantum/+bug/1174657
|
||||
'''
|
||||
osutils = osutils_factory.OSUtilsFactory().get_os_utils()
|
||||
|
||||
os_major_version = int(osutils.get_os_version().split('.')[0])
|
||||
if os_major_version >= 6:
|
||||
# 169.254.x.x addresses are not getting routed starting from
|
||||
# Windows Vista / 2008
|
||||
metadata_netloc = urlparse.urlparse(CONF.metadata_base_url).netloc
|
||||
metadata_host = metadata_netloc.split(':')[0]
|
||||
|
||||
if metadata_host.startswith("169.254."):
|
||||
if not osutils.check_static_route_exists(metadata_host):
|
||||
(interface_index, gateway) = osutils.get_default_gateway()
|
||||
if gateway:
|
||||
try:
|
||||
osutils.add_static_route(metadata_host,
|
||||
"255.255.255.255",
|
||||
gateway,
|
||||
interface_index,
|
||||
10)
|
||||
except Exception, ex:
|
||||
# Ignore it
|
||||
LOG.exception(ex)
|
||||
|
||||
def load(self):
|
||||
super(HttpService, self).load()
|
||||
|
||||
self._check_metadata_ip_route()
|
||||
|
||||
try:
|
||||
self.get_meta_data('openstack')
|
||||
return True
|
||||
|
@ -69,3 +69,16 @@ class BaseOSUtils(object):
|
||||
|
||||
def terminate(self):
|
||||
pass
|
||||
|
||||
def get_default_gateway(self):
|
||||
pass
|
||||
|
||||
def check_static_route_exists(self, destination):
|
||||
pass
|
||||
|
||||
def add_static_route(self, destination, mask, next_hop, interface_index,
|
||||
metric):
|
||||
pass
|
||||
|
||||
def get_os_version(self):
|
||||
pass
|
||||
|
@ -327,3 +327,48 @@ class WindowsUtils(base.BaseOSUtils):
|
||||
# is not enough
|
||||
time.sleep(3)
|
||||
self._stop_service(self._service_name)
|
||||
|
||||
def get_default_gateway(self):
|
||||
conn = wmi.WMI(moniker='//./root/cimv2')
|
||||
for net_adapter_config in conn.Win32_NetworkAdapterConfiguration():
|
||||
if net_adapter_config.DefaultIPGateway:
|
||||
return (net_adapter_config.InterfaceIndex,
|
||||
net_adapter_config.DefaultIPGateway[0])
|
||||
return (None, None)
|
||||
|
||||
def check_static_route_exists(self, destination):
|
||||
conn = wmi.WMI(moniker='//./root/cimv2')
|
||||
return len(conn.Win32_IP4RouteTable(Destination=destination)) > 0
|
||||
|
||||
def add_static_route(self, destination, mask, next_hop, interface_index,
|
||||
metric):
|
||||
args = ['ROUTE', 'ADD', destination, 'MASK', mask, next_hop]
|
||||
(out, err, ret_val) = self.execute_process(args)
|
||||
# Cannot use the return value to determine the outcome
|
||||
if err:
|
||||
raise Exception('Unable to add route: %(err)s' % locals())
|
||||
|
||||
# TODO(alexpilotti): The following code creates the route properly and
|
||||
# "route print" shows the added route, but routing to the destination
|
||||
# fails. This option would be preferable compared to spawning a
|
||||
# "ROUTE ADD" process.
|
||||
'''
|
||||
ROUTE_PROTOCOL_NETMGMT = 3
|
||||
ROUTE_TYPE_INDIRECT = 4
|
||||
|
||||
conn = wmi.WMI(moniker='//./root/cimv2')
|
||||
|
||||
route = conn.Win32_IP4RouteTable.SpawnInstance_()
|
||||
route.Destination = destination
|
||||
route.Mask = mask
|
||||
route.NextHop = next_hop
|
||||
route.InterfaceIndex = interface_index
|
||||
route.Metric1 = metric
|
||||
route.Protocol = self.ROUTE_PROTOCOL_NETMGMT
|
||||
route.Type = self.ROUTE_TYPE_INDIRECT
|
||||
route.Put_()
|
||||
'''
|
||||
|
||||
def get_os_version(self):
|
||||
conn = wmi.WMI(moniker='//./root/cimv2')
|
||||
return conn.Win32_OperatingSystem()[0].Version
|
||||
|
Loading…
x
Reference in New Issue
Block a user