mirror of
https://github.com/GNS3/gns3-server.git
synced 2024-11-16 16:54:51 +02:00
Fix bug with application id allocation for IOU nodes. Fixes #3079
This commit is contained in:
parent
362701f5aa
commit
5d1fdceb98
@ -174,6 +174,7 @@ class Project:
|
|||||||
self._links = {}
|
self._links = {}
|
||||||
self._drawings = {}
|
self._drawings = {}
|
||||||
self._snapshots = {}
|
self._snapshots = {}
|
||||||
|
self._computes = []
|
||||||
|
|
||||||
# List the available snapshots
|
# List the available snapshots
|
||||||
snapshot_dir = os.path.join(self.path, "snapshots")
|
snapshot_dir = os.path.join(self.path, "snapshots")
|
||||||
@ -564,6 +565,9 @@ class Project:
|
|||||||
if node_id in self._nodes:
|
if node_id in self._nodes:
|
||||||
return self._nodes[node_id]
|
return self._nodes[node_id]
|
||||||
|
|
||||||
|
if compute.id not in self._computes:
|
||||||
|
self._computes.append(compute.id)
|
||||||
|
|
||||||
if node_type == "iou":
|
if node_type == "iou":
|
||||||
async with self._iou_id_lock:
|
async with self._iou_id_lock:
|
||||||
# wait for a IOU node to be completely created before adding a new one
|
# wait for a IOU node to be completely created before adding a new one
|
||||||
@ -571,10 +575,10 @@ class Project:
|
|||||||
# to generate MAC addresses) when creating multiple IOU node at the same time
|
# to generate MAC addresses) when creating multiple IOU node at the same time
|
||||||
if "properties" in kwargs.keys():
|
if "properties" in kwargs.keys():
|
||||||
# allocate a new application id for nodes loaded from the project
|
# allocate a new application id for nodes loaded from the project
|
||||||
kwargs.get("properties")["application_id"] = get_next_application_id(self._controller.projects, compute)
|
kwargs.get("properties")["application_id"] = get_next_application_id(self._controller.projects, self._computes)
|
||||||
elif "application_id" not in kwargs.keys() and not kwargs.get("properties"):
|
elif "application_id" not in kwargs.keys() and not kwargs.get("properties"):
|
||||||
# allocate a new application id for nodes added to the project
|
# allocate a new application id for nodes added to the project
|
||||||
kwargs["application_id"] = get_next_application_id(self._controller.projects, compute)
|
kwargs["application_id"] = get_next_application_id(self._controller.projects, self._computes)
|
||||||
node = await self._create_node(compute, name, node_id, node_type, **kwargs)
|
node = await self._create_node(compute, name, node_id, node_type, **kwargs)
|
||||||
else:
|
else:
|
||||||
node = await self._create_node(compute, name, node_id, node_type, **kwargs)
|
node = await self._create_node(compute, name, node_id, node_type, **kwargs)
|
||||||
@ -604,6 +608,8 @@ class Project:
|
|||||||
self.remove_allocated_node_name(node.name)
|
self.remove_allocated_node_name(node.name)
|
||||||
del self._nodes[node.id]
|
del self._nodes[node.id]
|
||||||
await node.destroy()
|
await node.destroy()
|
||||||
|
# refresh the compute IDs list
|
||||||
|
self._computes = [n.compute.id for n in self.nodes.values()]
|
||||||
self.dump()
|
self.dump()
|
||||||
self.emit_notification("node.deleted", node.__json__())
|
self.emit_notification("node.deleted", node.__json__())
|
||||||
|
|
||||||
@ -931,6 +937,14 @@ class Project:
|
|||||||
topology = project_data["topology"]
|
topology = project_data["topology"]
|
||||||
for compute in topology.get("computes", []):
|
for compute in topology.get("computes", []):
|
||||||
await self.controller.add_compute(**compute)
|
await self.controller.add_compute(**compute)
|
||||||
|
|
||||||
|
# Get all compute used in the project
|
||||||
|
# used to allocate application IDs for IOU nodes.
|
||||||
|
for node in topology.get("nodes", []):
|
||||||
|
compute_id = node.get("compute_id")
|
||||||
|
if compute_id not in self._computes:
|
||||||
|
self._computes.append(compute_id)
|
||||||
|
|
||||||
for node in topology.get("nodes", []):
|
for node in topology.get("nodes", []):
|
||||||
compute = self.controller.get_compute(node.pop("compute_id"))
|
compute = self.controller.get_compute(node.pop("compute_id"))
|
||||||
name = node.pop("name")
|
name = node.pop("name")
|
||||||
|
@ -21,26 +21,27 @@ import logging
|
|||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def get_next_application_id(projects, compute):
|
def get_next_application_id(projects, computes):
|
||||||
"""
|
"""
|
||||||
Calculates free application_id from given nodes
|
Calculates free application_id from given nodes
|
||||||
|
|
||||||
:param projects: all projects managed by controller
|
:param projects: all projects managed by controller
|
||||||
:param compute: Compute instance
|
:param computes: all computes used by the project
|
||||||
:raises HTTPConflict when exceeds number
|
:raises HTTPConflict when exceeds number
|
||||||
:return: integer first free id
|
:return: integer first free id
|
||||||
"""
|
"""
|
||||||
|
|
||||||
nodes = []
|
nodes = []
|
||||||
|
|
||||||
# look for application id for in all nodes across all opened projects that share the same compute
|
# look for application id for in all nodes across all opened projects that share the same computes
|
||||||
for project in projects.values():
|
for project in projects.values():
|
||||||
if project.status == "opened" and compute in project.computes:
|
if project.status == "opened":
|
||||||
nodes.extend(list(project.nodes.values()))
|
nodes.extend(list(project.nodes.values()))
|
||||||
|
|
||||||
used = set([n.properties["application_id"] for n in nodes if n.node_type == "iou"])
|
used = set([n.properties["application_id"] for n in nodes if n.node_type == "iou" and n.compute.id in computes])
|
||||||
pool = set(range(1, 512))
|
pool = set(range(1, 512))
|
||||||
try:
|
try:
|
||||||
return (pool - used).pop()
|
application_id = (pool - used).pop()
|
||||||
|
return application_id
|
||||||
except KeyError:
|
except KeyError:
|
||||||
raise aiohttp.web.HTTPConflict(text="Cannot create a new IOU node (limit of 512 nodes across all opened projects using compute {} reached".format(compute.name))
|
raise aiohttp.web.HTTPConflict(text="Cannot create a new IOU node (limit of 512 nodes across all opened projects using the same computes)")
|
||||||
|
Loading…
Reference in New Issue
Block a user