nova-docker/novadocker/tests/virt/docker/test_vifs.py

489 lines
24 KiB
Python

# Copyright (c) 2013 VMware, Inc.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import mock
from nova.network import model as network_model
from nova import test
from novadocker.virt.docker import driver as docker_driver
from novadocker.virt.docker import vifs
class DockerGenericVIFDriverTestCase(test.TestCase):
REQUIRES_LOCKING = True
gateway_bridge_4 = network_model.IP(address='10.11.12.1', type='gateway')
dns_bridge_4 = network_model.IP(address='8.8.8.8', type=None)
ips_bridge_4 = [network_model.IP(address='101.168.1.9', type='fixed',
version=4)]
subnet_bridge_4 = network_model.Subnet(cidr='10.11.1.0/24',
dns=[dns_bridge_4],
gateway=gateway_bridge_4,
ips=ips_bridge_4,
routes=None)
network_bridge = network_model.Network(id='network-id-xxx-yyy-zzz',
bridge='br100',
label=None,
subnets=[subnet_bridge_4],
bridge_interface='eth0')
vif_bridge = network_model.VIF(id='920be2f4-2b98-411e-890a-69bcabb2a5a0',
address='00:11:22:33:44:55',
network=network_bridge,
type=network_model.VIF_TYPE_BRIDGE)
network_iovisor = network_model.Network(id='network-id-xxx-yyy-zzz',
bridge='br100',
label='net1',
subnets=[subnet_bridge_4],
bridge_interface='eth0')
vif_iovisor = network_model.VIF(id='920be2f4-2b98-411e-890a-69bcabb2a5a0',
address='00:11:22:33:44:55',
network=network_iovisor,
type=network_model.VIF_TYPE_IOVISOR)
def setUp(self):
super(DockerGenericVIFDriverTestCase, self).setUp()
def fake_fe_random_mac(self):
return 'fe:16:3e:ff:ff:ff'
self.stubs.Set(vifs.DockerGenericVIFDriver,
'_fe_random_mac',
fake_fe_random_mac)
def test_plug_vifs_bridge(self):
calls = [
mock.call('ip', 'link', 'add', 'name', 'tap920be2f4-2b',
'type', 'veth', 'peer', 'name', 'ns920be2f4-2b',
run_as_root=True),
mock.call('ip', 'link', 'set', 'tap920be2f4-2b', 'address',
'fe:16:3e:ff:ff:ff', run_as_root=True),
mock.call('brctl', 'addif', 'br100', 'tap920be2f4-2b',
run_as_root=True),
mock.call('ip', 'link', 'set', 'tap920be2f4-2b', 'up',
run_as_root=True)
]
network_info = [self.vif_bridge]
with mock.patch('nova.utils.execute') as ex:
driver = docker_driver.DockerDriver(object)
driver.plug_vifs({'name': 'fake_instance'}, network_info)
ex.assert_has_calls(calls)
def test_plug_vifs_bridge_two_interfaces(self):
calls = [
# interface 1
mock.call('ip', 'link', 'add', 'name', 'tap920be2f4-2b',
'type', 'veth', 'peer', 'name', 'ns920be2f4-2b',
run_as_root=True),
mock.call('ip', 'link', 'set', 'tap920be2f4-2b', 'address',
'fe:16:3e:ff:ff:ff', run_as_root=True),
mock.call('brctl', 'addif', 'br100', 'tap920be2f4-2b',
run_as_root=True),
mock.call('ip', 'link', 'set', 'tap920be2f4-2b', 'up',
run_as_root=True),
# interface 2
mock.call('ip', 'link', 'add', 'name', 'tap920be2f4-2b',
'type', 'veth', 'peer', 'name', 'ns920be2f4-2b',
run_as_root=True),
mock.call('ip', 'link', 'set', 'tap920be2f4-2b', 'address',
'fe:16:3e:ff:ff:ff', run_as_root=True),
mock.call('brctl', 'addif', 'br100', 'tap920be2f4-2b',
run_as_root=True),
mock.call('ip', 'link', 'set', 'tap920be2f4-2b', 'up',
run_as_root=True),
]
network_info = [self.vif_bridge, self.vif_bridge]
with mock.patch('nova.utils.execute') as ex:
driver = docker_driver.DockerDriver(object)
driver.plug_vifs({'name': 'fake_instance'}, network_info)
ex.assert_has_calls(calls)
def test_plug_vifs_ovs(self):
iface_id = '920be2f4-2b98-411e-890a-69bcabb2a5a0'
calls = [
mock.call('ip', 'link', 'add', 'name', 'tap920be2f4-2b',
'type', 'veth', 'peer', 'name', 'ns920be2f4-2b',
run_as_root=True),
mock.call('ovs-vsctl', '--timeout=120', '--', '--if-exists',
'del-port', 'tap920be2f4-2b', '--', 'add-port',
'br-int', 'tap920be2f4-2b',
'--', 'set', 'Interface', 'tap920be2f4-2b',
'external-ids:iface-id=%s' % iface_id,
'external-ids:iface-status=active',
'external-ids:attached-mac=00:11:22:33:44:55',
'external-ids:vm-uuid=instance_uuid',
run_as_root=True),
mock.call('ip', 'link', 'set', 'tap920be2f4-2b', 'up',
run_as_root=True),
]
network_info = [
{'network': {'bridge': 'br-int',
'subnets': [{'gateway': {'address': '10.11.12.1'},
'cidr': '10.11.12.0/24',
'ips': [{'address': '10.11.12.3',
'type': 'fixed', 'version': 4}]
}]},
'address': '00:11:22:33:44:55',
'id': iface_id,
'type': network_model.VIF_TYPE_OVS}]
with mock.patch('nova.utils.execute') as ex:
driver = docker_driver.DockerDriver(object)
driver.plug_vifs({'name': 'fake_instance',
'uuid': 'instance_uuid'}, network_info)
ex.assert_has_calls(calls)
def test_plug_vifs_ovs_hybrid(self):
iface_id = '920be2f4-2b98-411e-890a-69bcabb2a5a0'
calls = [
mock.call('brctl', 'addbr', 'qbr920be2f4-2b', run_as_root=True),
mock.call('brctl', 'setfd', 'qbr920be2f4-2b', 0, run_as_root=True),
mock.call('brctl', 'stp', 'qbr920be2f4-2b', 'off',
run_as_root=True),
mock.call('tee', "/sys/class/net/qbr920be2f4-2b/bridge/multicast_"
"snooping", run_as_root=True, process_input='0',
check_exit_code=[0, 1]),
mock.call('ip', 'link', 'add', 'qvb920be2f4-2b', 'type',
'veth', 'peer', 'name', 'qvo920be2f4-2b',
run_as_root=True),
mock.call('ip', 'link', 'set', 'qvb920be2f4-2b', 'up',
run_as_root=True),
mock.call('ip', 'link', 'set', 'qvb920be2f4-2b', 'promisc', 'on',
run_as_root=True),
mock.call('ip', 'link', 'set', 'qvo920be2f4-2b', 'up',
run_as_root=True),
mock.call('ip', 'link', 'set', 'qvo920be2f4-2b', 'promisc', 'on',
run_as_root=True),
mock.call('ip', 'link', 'set', 'qbr920be2f4-2b', 'up',
run_as_root=True),
mock.call('brctl', 'addif', 'qbr920be2f4-2b', 'qvb920be2f4-2b',
run_as_root=True),
mock.call('ovs-vsctl', '--timeout=120', '--', '--if-exists',
'del-port', 'qvo920be2f4-2b', '--', 'add-port',
'br-int', 'qvo920be2f4-2b', '--', 'set', 'Interface',
'qvo920be2f4-2b', "external-ids:iface-id=920be2f4-2b98-"
"411e-890a-69bcabb2a5a0",
'external-ids:iface-status=active',
'external-ids:attached-mac=00:11:22:33:44:55',
'external-ids:vm-uuid=instance_uuid', run_as_root=True),
mock.call('ip', 'link', 'add', 'name', 'tap920be2f4-2b', 'type',
'veth', 'peer', 'name', 'ns920be2f4-2b',
run_as_root=True),
mock.call('brctl', 'addif', 'qbr920be2f4-2b', 'tap920be2f4-2b',
run_as_root=True),
mock.call('ip', 'link', 'set', 'tap920be2f4-2b', 'up',
run_as_root=True),
]
network_info = [
{'network': {'bridge': 'br-int',
'subnets': [{'gateway': {'address': '10.11.12.1'},
'cidr': '10.11.12.0/24',
'ips': [{'address': '10.11.12.3',
'type': 'fixed', 'version': 4}]
}]},
'address': '00:11:22:33:44:55',
'id': iface_id,
'details': {'port_filter': True, 'ovs_hybrid_plug': True},
'type': network_model.VIF_TYPE_OVS}]
with mock.patch('nova.utils.execute') as ex:
driver = docker_driver.DockerDriver(object)
driver.plug_vifs({'name': 'fake_instance',
'uuid': 'instance_uuid'}, network_info)
ex.assert_has_calls(calls)
def test_unplug_vifs_ovs(self):
iface_id = '920be2f4-2b98-411e-890a-69bcabb2a5a0'
calls = [
mock.call('ovs-vsctl', '--timeout=120', '--', '--if-exists',
'del-port', 'br-int', 'tap920be2f4-2b',
run_as_root=True)
]
network_info = [
{'network': {'bridge': 'br-int',
'subnets': [{'gateway': {'address': '10.11.12.1'},
'cidr': '10.11.12.0/24',
'ips': [{'address': '10.11.12.3',
'type': 'fixed', 'version': 4}]
}]},
'devname': 'tap920be2f4-2b',
'address': '00:11:22:33:44:55',
'id': iface_id,
'type': network_model.VIF_TYPE_OVS}]
with mock.patch('nova.utils.execute') as ex:
driver = docker_driver.DockerDriver(object)
driver.unplug_vifs({'name': 'fake_instance',
'uuid': 'instance_uuid'}, network_info)
ex.assert_has_calls(calls)
def test_plug_vifs_midonet(self):
iface_id = '920be2f4-2b98-411e-890a-69bcabb2a5a0'
host_side_veth = 'tap920be2f4-2b'
calls = [
mock.call('ip', 'link', 'add', 'name', host_side_veth,
'type', 'veth', 'peer', 'name', 'ns920be2f4-2b',
run_as_root=True),
mock.call('ip', 'link', 'set', host_side_veth, 'up',
run_as_root=True),
mock.call('mm-ctl', '--bind-port', iface_id, host_side_veth,
run_as_root=True),
]
network_info = [{'id': iface_id,
'type': network_model.VIF_TYPE_MIDONET}]
with mock.patch('nova.utils.execute') as ex:
driver = docker_driver.DockerDriver(object)
driver.plug_vifs({'name': 'fake_instance',
'uuid': 'instance_uuid'}, network_info)
ex.assert_has_calls(calls)
def test_unplug_vifs_midonet(self):
iface_id = '920be2f4-2b98-411e-890a-69bcabb2a5a0'
calls = [
mock.call('mm-ctl', '--unbind-port', iface_id, run_as_root=True)
]
network_info = [{'id': iface_id,
'type': network_model.VIF_TYPE_MIDONET}]
with mock.patch('nova.utils.execute') as ex:
driver = docker_driver.DockerDriver(object)
driver.unplug_vifs({'name': 'fake_instance',
'uuid': 'instance_uuid'}, network_info)
ex.assert_has_calls(calls)
def test_plug_vifs_iovisor(self):
iface_id = '920be2f4-2b98-411e-890a-69bcabb2a5a0'
tenant_id = 'tenant1'
calls = [
mock.call('ip', 'link', 'add', 'name', 'tap920be2f4-2b', 'type',
'veth', 'peer', 'name', 'ns920be2f4-2b',
run_as_root=True),
mock.call('ifc_ctl', 'gateway', 'add_port', 'tap920be2f4-2b',
run_as_root=True),
mock.call('ifc_ctl', 'gateway', 'ifup', 'tap920be2f4-2b',
'access_vm', "net1_" + iface_id, '00:11:22:33:44:55',
'pgtag2=network-id-xxx-yyy-zzz',
'pgtag1=%s' % tenant_id, run_as_root=True),
mock.call('ip', 'link', 'set', 'tap920be2f4-2b', 'up',
run_as_root=True),
]
network_info = [self.vif_iovisor]
with mock.patch('nova.utils.execute') as ex:
driver = docker_driver.DockerDriver(object)
driver.plug_vifs({'name': 'fake_instance',
'uuid': 'instance_uuid',
'project_id': tenant_id}, network_info)
ex.assert_has_calls(calls)
def test_unplug_vifs_iovisor(self):
iface_id = '920be2f4-2b98-411e-890a-69bcabb2a5a0'
tenant_id = 'tenant1'
calls = [
mock.call('ifc_ctl', 'gateway', 'ifdown', 'tap920be2f4-2b',
'access_vm', 'net1_' + iface_id, '00:11:22:33:44:55',
run_as_root=True),
mock.call('ifc_ctl', 'gateway', 'del_port', 'tap920be2f4-2b',
run_as_root=True)
]
network_info = [self.vif_iovisor]
with mock.patch('nova.utils.execute') as ex:
driver = docker_driver.DockerDriver(object)
driver.unplug_vifs({'name': 'fake_instance',
'uuid': 'instance_uuid',
'project_id': tenant_id}, network_info)
ex.assert_has_calls(calls)
def test_plug_vifs_windows(self):
network_info = [{'type': 'hyperv'}]
fake_instance = mock.sentinel.instance
with mock.patch.object(vifs.DockerGenericVIFDriver,
'plug_windows') as mock_plug_windows:
driver = docker_driver.DockerDriver(object)
driver.plug_vifs(fake_instance, network_info)
mock_plug_windows.assert_called_once_with(
fake_instance, {'type': 'hyperv'})
def test_unplug_vifs_windows(self):
network_info = [{'type': 'hyperv'}]
fake_instance = mock.sentinel.instance
with mock.patch.object(vifs.DockerGenericVIFDriver,
'unplug_windows') as mock_unplug_windows:
driver = docker_driver.DockerDriver(object)
driver.unplug_vifs(fake_instance, network_info)
mock_unplug_windows.assert_called_once_with(
fake_instance, {'type': 'hyperv'})
def test_unplug_vifs_ovs_hybrid(self):
iface_id = '920be2f4-2b98-411e-890a-69bcabb2a5a0'
calls = [
mock.call('ovs-vsctl', '--timeout=120', '--', '--if-exists',
'del-port', 'br-int', 'qvo920be2f4-2b',
run_as_root=True)
]
network_info = [
{'network': {'bridge': 'br-int',
'subnets': [{'gateway': {'address': '10.11.12.1'},
'cidr': '10.11.12.0/24',
'ips': [{'address': '10.11.12.3',
'type': 'fixed', 'version': 4}]
}]},
'devname': 'tap920be2f4-2b',
'address': '00:11:22:33:44:55',
'id': iface_id,
'details': {'port_filter': True, 'ovs_hybrid_plug': True},
'type': network_model.VIF_TYPE_OVS}]
with mock.patch('nova.utils.execute') as ex:
driver = docker_driver.DockerDriver(object)
driver.unplug_vifs({'name': 'fake_instance',
'uuid': 'instance_uuid'}, network_info)
ex.assert_has_calls(calls)
@mock.patch.object(docker_driver.DockerDriver,
'_find_container_by_uuid',
return_value={'id': 'fake_id'})
@mock.patch.object(docker_driver.DockerDriver,
'_find_container_pid',
return_value=1234)
def test_attach_vifs(self, mock_find_by_uuid, mock_find_pid):
calls = [
mock.call('ln', '-sf', '/proc/1234/ns/net',
'/var/run/netns/fake_id', run_as_root=True),
mock.call('ip', 'netns', 'exec', 'fake_id', 'ip', 'link',
'set', 'lo', 'up', run_as_root=True),
mock.call('ip', 'link', 'set', 'ns920be2f4-2b', 'netns',
'fake_id', run_as_root=True),
mock.call('ip', 'netns', 'exec', 'fake_id', 'ip', 'link',
'set', 'ns920be2f4-2b', 'address', '00:11:22:33:44:55',
run_as_root=True),
mock.call('ip', 'netns', 'exec', 'fake_id',
'ip', 'addr', 'add', '10.11.12.3/24', 'dev',
'ns920be2f4-2b', run_as_root=True),
mock.call('ip', 'netns', 'exec', 'fake_id',
'ip', 'link', 'set',
'ns920be2f4-2b', 'up', run_as_root=True),
mock.call('ip', 'netns', 'exec', 'fake_id', 'ip', 'route',
'replace', 'default', 'via', '10.11.12.1', 'dev',
'ns920be2f4-2b', run_as_root=True),
mock.call('ip', 'netns', 'exec', 'fake_id', 'ethtool', '--offload',
'ns920be2f4-2b', 'tso', 'off', run_as_root=True)
]
network_info = [
{'network': {'bridge': 'br100',
'subnets': [{'gateway': {'address': '10.11.12.1'},
'cidr': '10.11.12.0/24',
'ips': [{'address': '10.11.12.3',
'type': 'fixed', 'version': 4}]
}]},
'address': '00:11:22:33:44:55',
'id': '920be2f4-2b98-411e-890a-69bcabb2a5a0',
'type': network_model.VIF_TYPE_BRIDGE}]
with mock.patch('nova.utils.execute') as ex:
driver = docker_driver.DockerDriver(object)
driver._attach_vifs({'uuid': 'fake_uuid'}, network_info)
ex.assert_has_calls(calls)
@mock.patch.object(docker_driver.DockerDriver,
'_find_container_by_uuid',
return_value={'id': 'fake_id'})
@mock.patch.object(docker_driver.DockerDriver,
'_find_container_pid',
return_value=1234)
def test_attach_vifs_two_interfaces(self, mock_find_by_uuid,
mock_find_pid):
calls = [
mock.call('ln', '-sf', '/proc/1234/ns/net',
'/var/run/netns/fake_id', run_as_root=True),
mock.call('ip', 'netns', 'exec', 'fake_id', 'ip', 'link',
'set', 'lo', 'up', run_as_root=True),
# interface 1
mock.call('ip', 'link', 'set', 'ns920be2f4-2b', 'netns', 'fake_id',
run_as_root=True),
mock.call('ip', 'netns', 'exec', 'fake_id', 'ip', 'link',
'set', 'ns920be2f4-2b', 'address', '00:11:22:33:44:55',
run_as_root=True),
mock.call('ip', 'netns', 'exec', 'fake_id',
'ip', 'addr', 'add', '10.11.12.3/24', 'dev',
'ns920be2f4-2b', run_as_root=True),
mock.call('ip', 'netns', 'exec', 'fake_id',
'ip', 'link', 'set',
'ns920be2f4-2b', 'up', run_as_root=True),
mock.call('ip', 'netns', 'exec', 'fake_id', 'ip', 'route',
'replace', 'default', 'via', '10.11.12.1', 'dev',
'ns920be2f4-2b', run_as_root=True),
mock.call('ip', 'netns', 'exec', 'fake_id', 'ethtool', '--offload',
'ns920be2f4-2b', 'tso', 'off', run_as_root=True),
# interface 2
mock.call('ip', 'link', 'set', 'ns920be2f4-2b', 'netns', 'fake_id',
run_as_root=True),
mock.call('ip', 'netns', 'exec', 'fake_id', 'ip', 'link',
'set', 'ns920be2f4-2b', 'address', '00:11:22:33:44:66',
run_as_root=True),
mock.call('ip', 'netns', 'exec', 'fake_id',
'ip', 'addr', 'add', '10.13.12.3/24', 'dev',
'ns920be2f4-2b', run_as_root=True),
mock.call('ip', 'netns', 'exec', 'fake_id',
'ip', 'link', 'set',
'ns920be2f4-2b', 'up', run_as_root=True),
mock.call('ip', 'netns', 'exec', 'fake_id', 'ip', 'route',
'replace', 'default', 'via', '10.13.12.1', 'dev',
'ns920be2f4-2b', run_as_root=True),
mock.call('ip', 'netns', 'exec', 'fake_id', 'ethtool', '--offload',
'ns920be2f4-2b', 'tso', 'off', run_as_root=True)
]
network_info = [
{'network': {'bridge': 'br100',
'subnets': [{'gateway': {'address': '10.11.12.1'},
'cidr': '10.11.12.0/24',
'ips': [{'address': '10.11.12.3',
'type': 'fixed', 'version': 4}],
}]},
'address': '00:11:22:33:44:55',
'type': network_model.VIF_TYPE_BRIDGE,
'id': '920be2f4-2b98-411e-890a-69bcabb2a5a0'},
{'network': {'bridge': 'br100',
'subnets': [{'gateway': {'address': '10.13.12.1'},
'cidr': '10.13.12.0/24',
'ips': [{'address': '10.13.12.3',
'type': 'fixed', 'version': 4}]
}]},
'address': '00:11:22:33:44:66',
'type': network_model.VIF_TYPE_BRIDGE,
'id': '920be2f4-2b98-411e-890a-69bcabb2a5a0'}]
with mock.patch('nova.utils.execute') as ex:
driver = docker_driver.DockerDriver(object)
driver._attach_vifs({'uuid': 'fake_uuid'}, network_info)
ex.assert_has_calls(calls)
@mock.patch.object(docker_driver, 'os')
def test_attach_vifs_hyperv(self, mock_os):
mock_os.name = 'nt'
with mock.patch.object(docker_driver.DockerDriver,
'_get_container_id') as mock_get_container_id:
driver = docker_driver.DockerDriver(object)
driver._attach_vifs(mock.sentinel.instance,
mock.sentinel.network_info)
self.assertFalse(mock_get_container_id.called)