mirror of
https://github.com/GNS3/gns3-server.git
synced 2025-06-16 22:38:18 +00:00
Allocate application IDs for IOU nodes on the controller.
An application ID is used by IOU to generate its interface Mac addresses. They must be unique across all opened projects sharing the same computes to avoid Mac address collisions.
This commit is contained in:
@ -38,6 +38,7 @@ from .topology import project_to_topology, load_topology
|
||||
from .udp_link import UDPLink
|
||||
from ..config import Config
|
||||
from ..utils.path import check_path_allowed, get_default_project_directory
|
||||
from ..utils.application_id import get_next_application_id
|
||||
from ..utils.asyncio.pool import Pool
|
||||
from ..utils.asyncio import locking
|
||||
from ..utils.asyncio import aiozipstream
|
||||
@ -126,6 +127,8 @@ class Project:
|
||||
assert self._status != "closed"
|
||||
self.dump()
|
||||
|
||||
self._iou_id_lock = asyncio.Lock()
|
||||
|
||||
def emit_notification(self, action, event):
|
||||
"""
|
||||
Emit a notification to all clients using this project.
|
||||
@ -516,17 +519,7 @@ class Project:
|
||||
node = await self.add_node(compute, name, node_id, node_type=node_type, **template)
|
||||
return node
|
||||
|
||||
@open_required
|
||||
async def add_node(self, compute, name, node_id, dump=True, node_type=None, **kwargs):
|
||||
"""
|
||||
Create a node or return an existing node
|
||||
|
||||
:param dump: Dump topology to disk
|
||||
:param kwargs: See the documentation of node
|
||||
"""
|
||||
|
||||
if node_id in self._nodes:
|
||||
return self._nodes[node_id]
|
||||
async def _create_node(self, compute, name, node_id, node_type=None, **kwargs):
|
||||
|
||||
node = Node(self, compute, name, node_id=node_id, node_type=node_type, **kwargs)
|
||||
if compute not in self._project_created_on_compute:
|
||||
@ -547,10 +540,39 @@ class Project:
|
||||
data["variables"] = self._variables
|
||||
|
||||
await compute.post("/projects", data=data)
|
||||
|
||||
self._project_created_on_compute.add(compute)
|
||||
|
||||
await node.create()
|
||||
self._nodes[node.id] = node
|
||||
|
||||
return node
|
||||
|
||||
@open_required
|
||||
async def add_node(self, compute, name, node_id, dump=True, node_type=None, **kwargs):
|
||||
"""
|
||||
Create a node or return an existing node
|
||||
|
||||
:param dump: Dump topology to disk
|
||||
:param kwargs: See the documentation of node
|
||||
"""
|
||||
|
||||
if node_id in self._nodes:
|
||||
return self._nodes[node_id]
|
||||
|
||||
if node_type == "iou":
|
||||
async with self._iou_id_lock:
|
||||
# wait for a IOU node to be completely created before adding a new one
|
||||
# this is important otherwise we allocate the same application ID (used
|
||||
# to generate MAC addresses) when creating multiple IOU node at the same time
|
||||
if "properties" in kwargs.keys():
|
||||
# allocate a new application id for nodes loaded from the project
|
||||
kwargs.get("properties")["application_id"] = get_next_application_id(self._controller.projects, compute)
|
||||
elif "application_id" not in kwargs.keys() and not kwargs.get("properties"):
|
||||
# allocate a new application id for nodes added to the project
|
||||
kwargs["application_id"] = get_next_application_id(self._controller.projects, compute)
|
||||
node = await self._create_node(compute, name, node_id, node_type, **kwargs)
|
||||
else:
|
||||
node = await self._create_node(compute, name, node_id, node_type, **kwargs)
|
||||
self.emit_notification("node.created", node.__json__())
|
||||
if dump:
|
||||
self.dump()
|
||||
@ -1102,12 +1124,11 @@ class Project:
|
||||
data['z'] = z
|
||||
data['locked'] = False # duplicated node must not be locked
|
||||
new_node_uuid = str(uuid.uuid4())
|
||||
new_node = await self.add_node(
|
||||
node.compute,
|
||||
node.name,
|
||||
new_node_uuid,
|
||||
node_type=node_type,
|
||||
**data)
|
||||
new_node = await self.add_node(node.compute,
|
||||
node.name,
|
||||
new_node_uuid,
|
||||
node_type=node_type,
|
||||
**data)
|
||||
try:
|
||||
await node.post("/duplicate", timeout=None, data={
|
||||
"destination_node_id": new_node_uuid
|
||||
|
Reference in New Issue
Block a user