Skip to content

Commit 3214f52

Browse files
committed
Merge branch '2.2' into 3.0
# Conflicts: # gns3server/compute/docker/docker_vm.py # gns3server/handlers/api/compute/docker_handler.py # gns3server/schemas/docker.py # gns3server/schemas/docker_template.py # tests/compute/docker/test_docker_vm.py
2 parents 9bcf26b + ddd6235 commit 3214f52

File tree

3 files changed

+61
-3
lines changed

3 files changed

+61
-3
lines changed

gns3server/compute/docker/docker_vm.py

+51-1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
from gns3server.utils.asyncio import monitor_process
3535
from gns3server.utils.get_resource import get_resource
3636
from gns3server.utils.hostname import is_rfc1123_hostname_valid
37+
from gns3server.utils import macaddress_to_int, int_to_macaddress
3738

3839
from gns3server.compute.ubridge.ubridge_error import UbridgeError, UbridgeNamespaceError
3940
from ..base_node import BaseNode
@@ -105,6 +106,7 @@ def __init__(
105106
self._environment = environment
106107
self._cid = None
107108
self._ethernet_adapters = []
109+
self._mac_address = ""
108110
self._temporary_directory = None
109111
self._telnet_servers = []
110112
self._vnc_process = None
@@ -130,6 +132,8 @@ def __init__(
130132
else:
131133
self.adapters = adapters
132134

135+
self.mac_address = "" # this will generate a MAC address
136+
133137
log.debug(
134138
"{module}: {name} [{image}] initialized.".format(
135139
module=self.manager.module_name, name=self.name, image=self._image
@@ -145,6 +149,7 @@ def asdict(self):
145149
"project_id": self._project.id,
146150
"image": self._image,
147151
"adapters": self.adapters,
152+
"mac_address": self.mac_address,
148153
"console": self.console,
149154
"console_type": self.console_type,
150155
"console_resolution": self.console_resolution,
@@ -190,6 +195,36 @@ def name(self, new_name):
190195
def ethernet_adapters(self):
191196
return self._ethernet_adapters
192197

198+
@property
199+
def mac_address(self):
200+
"""
201+
Returns the MAC address for this Docker container.
202+
203+
:returns: adapter type (string)
204+
"""
205+
206+
return self._mac_address
207+
208+
@mac_address.setter
209+
def mac_address(self, mac_address):
210+
"""
211+
Sets the MAC address for this Docker container.
212+
213+
:param mac_address: MAC address
214+
"""
215+
216+
if not mac_address:
217+
# use the node UUID to generate a random MAC address
218+
self._mac_address = "02:42:%s:%s:%s:00" % (self.id[2:4], self.id[4:6], self.id[6:8])
219+
else:
220+
self._mac_address = mac_address
221+
222+
log.info('Docker container "{name}" [{id}]: MAC address changed to {mac_addr}'.format(
223+
name=self._name,
224+
id=self._id,
225+
mac_addr=self._mac_address)
226+
)
227+
193228
@property
194229
def start_command(self):
195230
return self._start_command
@@ -1058,7 +1093,20 @@ async def _add_ubridge_connection(self, nio, adapter_number):
10581093
adapter_number=adapter_number, hostif=adapter.host_ifc
10591094
)
10601095
)
1061-
log.debug("Move container %s adapter %s to namespace %s", self.name, adapter.host_ifc, self._namespace)
1096+
1097+
mac_address = int_to_macaddress(macaddress_to_int(self._mac_address) + adapter_number)
1098+
custom_adapter = self._get_custom_adapter_settings(adapter_number)
1099+
custom_mac_address = custom_adapter.get("mac_address")
1100+
if custom_mac_address:
1101+
mac_address = custom_mac_address
1102+
1103+
try:
1104+
await self._ubridge_send('docker set_mac_addr {ifc} {mac}'.format(ifc=adapter.host_ifc, mac=mac_address))
1105+
except UbridgeError:
1106+
log.warning(f"Could not set MAC address {mac_address} on interface {adapter.host_ifc}")
1107+
1108+
1109+
log.debug(f"Move container {self.name} adapter {adapter.host_ifc} to namespace {self._namespace}")
10621110
try:
10631111
await self._ubridge_send(
10641112
"docker move_to_ns {ifc} {ns} eth{adapter}".format(
@@ -1067,6 +1115,8 @@ async def _add_ubridge_connection(self, nio, adapter_number):
10671115
)
10681116
except UbridgeError as e:
10691117
raise UbridgeNamespaceError(e)
1118+
else:
1119+
log.info(f"Created adapter {adapter_number} with MAC address {mac_address} in namespace {self._namespace}")
10701120

10711121
if nio:
10721122
await self._connect_nio(adapter_number, nio)

gns3server/controller/node.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@
2929
)
3030
from .ports.port_factory import PortFactory, StandardPortFactory, DynamipsPortFactory
3131
from ..utils.images import images_directories
32+
from ..utils import macaddress_to_int, int_to_macaddress
3233
from ..config import Config
33-
from ..utils.qt import qt_font_to_style
3434

3535

3636
import logging
@@ -758,7 +758,13 @@ def _list_ports(self):
758758
break
759759
port_name = f"eth{adapter_number}"
760760
port_name = custom_adapter_settings.get("port_name", port_name)
761-
self._ports.append(PortFactory(port_name, 0, adapter_number, 0, "ethernet", short_name=port_name))
761+
mac_address = custom_adapter_settings.get("mac_address")
762+
if not mac_address and "mac_address" in self._properties:
763+
mac_address = int_to_macaddress(macaddress_to_int(self._properties["mac_address"]) + adapter_number)
764+
765+
port = PortFactory(port_name, 0, adapter_number, 0, "ethernet", short_name=port_name)
766+
port.mac_address = mac_address
767+
self._ports.append(port)
762768
elif self._node_type in ("ethernet_switch", "ethernet_hub"):
763769
# Basic node we don't want to have adapter number
764770
port_number = 0

tests/compute/docker/test_docker_vm.py

+2
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ async def vm(compute_project, manager):
4747

4848
vm = DockerVM("test", str(uuid.uuid4()), compute_project, manager, "ubuntu:latest", aux_type="none")
4949
vm._cid = "e90e34656842"
50+
vm.mac_address = '02:42:3d:b7:93:00'
5051
return vm
5152

5253

@@ -59,6 +60,7 @@ def test_json(vm, compute_project):
5960
'project_id': compute_project.id,
6061
'node_id': vm.id,
6162
'adapters': 1,
63+
'mac_address': '02:42:3d:b7:93:00',
6264
'console': vm.console,
6365
'console_type': 'telnet',
6466
'aux_type': 'none',

0 commit comments

Comments
 (0)