Nova Docker: Metadata service doesn't work

The metadata services rejects the request because the remote IP address
belongs to the docker network. The remote IP address is correct by using
the nova network as default route.

Change-Id: I410a9bfea560f669515b31db7f007515b4d5c4e7
Closes-Bug: #1259267
Closes-Bug: #1261021
This commit is contained in:
Daniel Kuffner 2013-12-15 09:53:17 +01:00
parent e1f5d91600
commit 709410d243
3 changed files with 61 additions and 9 deletions

View File

@ -15,10 +15,14 @@
# License for the specific language governing permissions and limitations
# under the License.
import uuid
from nova import exception
from nova import test
from nova import utils
from nova.tests import utils as test_utils
from nova.openstack.common import processutils
from nova.virt.docker import network
@ -50,3 +54,36 @@ class NetworkTestCase(test.NoDBTestCase):
id = "third-id"
network.teardown_network(id)
log_mock.warning.assert_called_with(mock.ANY, id)
def test_find_gateway(self):
instance = {'uuid': uuid.uuid4()}
network_info = test_utils.get_test_network_info()
first_net = network_info[0]['network']
first_net['subnets'][0]['gateway']['address'] = '10.0.0.1'
self.assertEqual('10.0.0.1', network.find_gateway(instance, first_net))
def test_cannot_find_gateway(self):
instance = {'uuid': uuid.uuid4()}
network_info = test_utils.get_test_network_info()
first_net = network_info[0]['network']
first_net['subnets'] = []
self.assertRaises(exception.InstanceDeployFailure,
network.find_gateway, instance, first_net)
def test_find_fixed_ip(self):
instance = {'uuid': uuid.uuid4()}
network_info = test_utils.get_test_network_info()
first_net = network_info[0]['network']
first_net['subnets'][0]['cidr'] = '10.0.0.0/24'
first_net['subnets'][0]['ips'][0]['type'] = 'fixed'
first_net['subnets'][0]['ips'][0]['address'] = '10.0.1.13'
self.assertEqual('10.0.1.13/24', network.find_fixed_ip(instance,
first_net))
def test_cannot_find_fixed_ip(self):
instance = {'uuid': uuid.uuid4()}
network_info = test_utils.get_test_network_info()
first_net = network_info[0]['network']
first_net['subnets'] = []
self.assertRaises(exception.InstanceDeployFailure,
network.find_fixed_ip, instance, first_net)

View File

@ -190,12 +190,6 @@ class DockerDriver(driver.ComputeDriver):
time.sleep(0.5)
n += 1
def _find_fixed_ip(self, subnets):
for subnet in subnets:
for ip in subnet['ips']:
if ip['type'] == 'fixed' and ip['address']:
return ip['address']
def _setup_network(self, instance, network_info):
if not network_info:
return
@ -220,9 +214,8 @@ class DockerDriver(driver.ComputeDriver):
if_local_name = 'pvnetl{0}'.format(rand)
if_remote_name = 'pvnetr{0}'.format(rand)
bridge = network_info['bridge']
ip = self._find_fixed_ip(network_info['subnets'])
if not ip:
raise RuntimeError(_('Cannot set fixed ip'))
gateway = network.find_gateway(instance, network_info)
ip = network.find_fixed_ip(instance, network_info)
undo_mgr = utils.UndoManager()
try:
utils.execute(
@ -246,6 +239,10 @@ class DockerDriver(driver.ComputeDriver):
'ip', 'netns', 'exec', container_id, 'ifconfig',
if_remote_name, ip,
run_as_root=True)
utils.execute(
'ip', 'netns', 'exec', container_id,
'ip', 'route', 'replace', 'default', 'via', gateway, 'dev',
if_remote_name, run_as_root=True)
except Exception:
msg = _('Failed to setup the network, rolling back')
undo_mgr.rollback_and_reraise(msg=msg, instance=instance)

View File

@ -15,6 +15,7 @@
# License for the specific language governing permissions and limitations
# under the License.
from nova import exception
from nova.openstack.common.gettextutils import _
from nova.openstack.common import log
from nova.openstack.common import processutils
@ -34,3 +35,20 @@ def teardown_network(container_id):
except processutils.ProcessExecutionError:
LOG.warning(_('Cannot remove network namespace, netns id: %s'),
container_id)
def find_fixed_ip(instance, network_info):
for subnet in network_info['subnets']:
netmask = subnet['cidr'].split('/')[1]
for ip in subnet['ips']:
if ip['type'] == 'fixed' and ip['address']:
return ip['address'] + "/" + netmask
raise exception.InstanceDeployFailure(_('Cannot find fixed ip'),
instance_id=instance['uuid'])
def find_gateway(instance, network_info):
for subnet in network_info['subnets']:
return subnet['gateway']['address']
raise exception.InstanceDeployFailure(_('Cannot find gateway'),
instance_id=instance['uuid'])