mirror of
https://github.com/GNS3/gns3-server
synced 2024-11-25 01:38:08 +00:00
parent
56658756e2
commit
89e86b7778
@ -168,9 +168,8 @@ class DockerVM(BaseVM):
|
|||||||
yield from self._start_ubridge()
|
yield from self._start_ubridge()
|
||||||
for adapter_number in range(0, self.adapters):
|
for adapter_number in range(0, self.adapters):
|
||||||
nio = self._ethernet_adapters[adapter_number].get_nio(0)
|
nio = self._ethernet_adapters[adapter_number].get_nio(0)
|
||||||
if nio:
|
with (yield from self.manager.ubridge_lock):
|
||||||
with (yield from self.manager.ubridge_lock):
|
yield from self._add_ubridge_connection(nio, adapter_number)
|
||||||
yield from self._add_ubridge_connection(nio, adapter_number)
|
|
||||||
|
|
||||||
yield from self._start_console()
|
yield from self._start_console()
|
||||||
|
|
||||||
@ -339,7 +338,7 @@ class DockerVM(BaseVM):
|
|||||||
"""
|
"""
|
||||||
Creates a connection in uBridge.
|
Creates a connection in uBridge.
|
||||||
|
|
||||||
:param nio: NIO instance
|
:param nio: NIO instance or None if it's a dummu interface (if an interface is missing in ubridge you can't see it via ifconfig in the container)
|
||||||
:param adapter_number: adapter number
|
:param adapter_number: adapter number
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
@ -348,19 +347,16 @@ class DockerVM(BaseVM):
|
|||||||
raise DockerError(
|
raise DockerError(
|
||||||
"Adapter {adapter_number} doesn't exist on Docker container '{name}'".format(name=self.name, adapter_number=adapter_number))
|
"Adapter {adapter_number} doesn't exist on Docker container '{name}'".format(name=self.name, adapter_number=adapter_number))
|
||||||
|
|
||||||
if nio and isinstance(nio, NIOUDP):
|
for index in range(128):
|
||||||
for index in range(128):
|
if "gns3-veth{}ext".format(index) not in psutil.net_if_addrs():
|
||||||
if "gns3-veth{}ext".format(index) not in psutil.net_if_addrs():
|
adapter.ifc = "eth{}".format(str(index))
|
||||||
adapter.ifc = "eth{}".format(str(index))
|
adapter.host_ifc = "gns3-veth{}ext".format(str(index))
|
||||||
adapter.host_ifc = "gns3-veth{}ext".format(str(index))
|
adapter.guest_ifc = "gns3-veth{}int".format(str(index))
|
||||||
adapter.guest_ifc = "gns3-veth{}int".format(str(index))
|
break
|
||||||
break
|
if not hasattr(adapter, "ifc"):
|
||||||
if not hasattr(adapter, "ifc"):
|
raise DockerError(
|
||||||
raise DockerError(
|
"Adapter {adapter_number} couldn't allocate interface on Docker container '{name}'. Too many Docker interfaces already exists".format(
|
||||||
"Adapter {adapter_number} couldn't allocate interface on Docker container '{name}'. Too many Docker interfaces already exists".format(
|
name=self.name, adapter_number=adapter_number))
|
||||||
name=self.name, adapter_number=adapter_number))
|
|
||||||
else:
|
|
||||||
raise ValueError("Invalid NIO")
|
|
||||||
|
|
||||||
yield from self._ubridge_hypervisor.send(
|
yield from self._ubridge_hypervisor.send(
|
||||||
'docker create_veth {hostif} {guestif}'.format(
|
'docker create_veth {hostif} {guestif}'.format(
|
||||||
@ -372,25 +368,25 @@ class DockerVM(BaseVM):
|
|||||||
'docker move_to_ns {ifc} {ns} eth{adapter}'.format(
|
'docker move_to_ns {ifc} {ns} eth{adapter}'.format(
|
||||||
ifc=adapter.guest_ifc, ns=namespace, adapter=adapter_number))
|
ifc=adapter.guest_ifc, ns=namespace, adapter=adapter_number))
|
||||||
|
|
||||||
yield from self._ubridge_hypervisor.send(
|
|
||||||
'bridge create bridge{}'.format(adapter_number))
|
|
||||||
yield from self._ubridge_hypervisor.send(
|
|
||||||
'bridge add_nio_linux_raw bridge{adapter} {ifc}'.format(
|
|
||||||
ifc=adapter.host_ifc, adapter=adapter_number))
|
|
||||||
|
|
||||||
if isinstance(nio, NIOUDP):
|
if isinstance(nio, NIOUDP):
|
||||||
|
yield from self._ubridge_hypervisor.send(
|
||||||
|
'bridge create bridge{}'.format(adapter_number))
|
||||||
|
yield from self._ubridge_hypervisor.send(
|
||||||
|
'bridge add_nio_linux_raw bridge{adapter} {ifc}'.format(
|
||||||
|
ifc=adapter.host_ifc, adapter=adapter_number))
|
||||||
|
|
||||||
yield from self._ubridge_hypervisor.send(
|
yield from self._ubridge_hypervisor.send(
|
||||||
'bridge add_nio_udp bridge{adapter} {lport} {rhost} {rport}'.format(
|
'bridge add_nio_udp bridge{adapter} {lport} {rhost} {rport}'.format(
|
||||||
adapter=adapter_number, lport=nio.lport, rhost=nio.rhost,
|
adapter=adapter_number, lport=nio.lport, rhost=nio.rhost,
|
||||||
rport=nio.rport))
|
rport=nio.rport))
|
||||||
|
|
||||||
if nio.capturing:
|
if nio.capturing:
|
||||||
yield from self._ubridge_hypervisor.send(
|
yield from self._ubridge_hypervisor.send(
|
||||||
'bridge start_capture bridge{adapter} "{pcap_file}"'.format(
|
'bridge start_capture bridge{adapter} "{pcap_file}"'.format(
|
||||||
adapter=adapter_number, pcap_file=nio.pcap_output_file))
|
adapter=adapter_number, pcap_file=nio.pcap_output_file))
|
||||||
|
|
||||||
yield from self._ubridge_hypervisor.send(
|
yield from self._ubridge_hypervisor.send(
|
||||||
'bridge start bridge{adapter}'.format(adapter=adapter_number))
|
'bridge start bridge{adapter}'.format(adapter=adapter_number))
|
||||||
|
|
||||||
def _delete_ubridge_connection(self, adapter_number):
|
def _delete_ubridge_connection(self, adapter_number):
|
||||||
"""Deletes a connection in uBridge.
|
"""Deletes a connection in uBridge.
|
||||||
|
@ -251,6 +251,31 @@ def test_start(loop, vm, manager, free_console_port):
|
|||||||
assert vm.status == "started"
|
assert vm.status == "started"
|
||||||
|
|
||||||
|
|
||||||
|
def test_start_without_nio(loop, vm, manager, free_console_port):
|
||||||
|
"""
|
||||||
|
If no nio exists we will create one.
|
||||||
|
"""
|
||||||
|
|
||||||
|
assert vm.status != "started"
|
||||||
|
vm.adapters = 1
|
||||||
|
|
||||||
|
# nio = manager.create_nio(0, {"type": "nio_udp", "lport": free_console_port, "rport": free_console_port, "rhost": "127.0.0.1"})
|
||||||
|
# loop.run_until_complete(asyncio.async(vm.adapter_add_nio_binding(0, nio)))
|
||||||
|
|
||||||
|
with asyncio_patch("gns3server.modules.docker.DockerVM._get_container_state", return_value="stopped"):
|
||||||
|
with asyncio_patch("gns3server.modules.docker.Docker.query") as mock_query:
|
||||||
|
with asyncio_patch("gns3server.modules.docker.DockerVM._start_ubridge") as mock_start_ubridge:
|
||||||
|
with asyncio_patch("gns3server.modules.docker.DockerVM._add_ubridge_connection") as mock_add_ubridge_connection:
|
||||||
|
with asyncio_patch("gns3server.modules.docker.DockerVM._start_console") as mock_start_console:
|
||||||
|
loop.run_until_complete(asyncio.async(vm.start()))
|
||||||
|
|
||||||
|
mock_query.assert_called_with("POST", "containers/e90e34656842/start")
|
||||||
|
assert mock_add_ubridge_connection.called
|
||||||
|
assert mock_start_ubridge.called
|
||||||
|
assert mock_start_console.called
|
||||||
|
assert vm.status == "started"
|
||||||
|
|
||||||
|
|
||||||
def test_start_unpause(loop, vm, manager, free_console_port):
|
def test_start_unpause(loop, vm, manager, free_console_port):
|
||||||
|
|
||||||
with asyncio_patch("gns3server.modules.docker.DockerVM._get_container_state", return_value="paused"):
|
with asyncio_patch("gns3server.modules.docker.DockerVM._get_container_state", return_value="paused"):
|
||||||
@ -370,29 +395,6 @@ def test_get_namespace(loop, vm):
|
|||||||
mock_query.assert_called_with("GET", "containers/e90e34656842/json")
|
mock_query.assert_called_with("GET", "containers/e90e34656842/json")
|
||||||
|
|
||||||
|
|
||||||
def test_add_ubridge_connection(loop, vm):
|
|
||||||
|
|
||||||
nio = {"type": "nio_udp",
|
|
||||||
"lport": 4242,
|
|
||||||
"rport": 4343,
|
|
||||||
"rhost": "127.0.0.1"}
|
|
||||||
nio = vm.manager.create_nio(0, nio)
|
|
||||||
vm._ubridge_hypervisor = MagicMock()
|
|
||||||
with asyncio_patch("gns3server.modules.docker.DockerVM._get_namespace", return_value=42):
|
|
||||||
loop.run_until_complete(asyncio.async(vm._add_ubridge_connection(nio, 0)))
|
|
||||||
|
|
||||||
calls = [
|
|
||||||
call.send("docker create_veth gns3-veth0ext gns3-veth0int"),
|
|
||||||
call.send('docker move_to_ns gns3-veth0int 42'),
|
|
||||||
call.send('bridge create bridge0'),
|
|
||||||
call.send('bridge add_nio_linux_raw bridge0 gns3-veth0ext'),
|
|
||||||
call.send('bridge add_nio_udp bridge0 4242 127.0.0.1 4343'),
|
|
||||||
call.send('bridge start bridge0')
|
|
||||||
]
|
|
||||||
# We need to check any_order ortherwise mock is confused by asyncio
|
|
||||||
vm._ubridge_hypervisor.assert_has_calls(calls, any_order=True)
|
|
||||||
|
|
||||||
|
|
||||||
def test_add_ubridge_connection(loop, vm):
|
def test_add_ubridge_connection(loop, vm):
|
||||||
|
|
||||||
nio = {"type": "nio_udp",
|
nio = {"type": "nio_udp",
|
||||||
@ -418,10 +420,19 @@ def test_add_ubridge_connection(loop, vm):
|
|||||||
vm._ubridge_hypervisor.assert_has_calls(calls, any_order=True)
|
vm._ubridge_hypervisor.assert_has_calls(calls, any_order=True)
|
||||||
|
|
||||||
|
|
||||||
def test_add_ubridge_connection_invalid_nio(loop, vm):
|
def test_add_ubridge_connection_none_nio(loop, vm):
|
||||||
|
|
||||||
with pytest.raises(ValueError):
|
nio = None
|
||||||
loop.run_until_complete(asyncio.async(vm._add_ubridge_connection({}, 0)))
|
vm._ubridge_hypervisor = MagicMock()
|
||||||
|
with asyncio_patch("gns3server.modules.docker.DockerVM._get_namespace", return_value=42):
|
||||||
|
loop.run_until_complete(asyncio.async(vm._add_ubridge_connection(nio, 0)))
|
||||||
|
|
||||||
|
calls = [
|
||||||
|
call.send("docker create_veth gns3-veth0ext gns3-veth0int"),
|
||||||
|
call.send('docker move_to_ns gns3-veth0int 42 eth0'),
|
||||||
|
]
|
||||||
|
# We need to check any_order ortherwise mock is confused by asyncio
|
||||||
|
vm._ubridge_hypervisor.assert_has_calls(calls, any_order=True)
|
||||||
|
|
||||||
|
|
||||||
def test_add_ubridge_connection_invalid_adapter_number(loop, vm):
|
def test_add_ubridge_connection_invalid_adapter_number(loop, vm):
|
||||||
|
Loading…
Reference in New Issue
Block a user