mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-11-03 05:51:15 +02:00
feat: allocate IOL Docker application IDs from a pool disjoint from IOU
IOL interface MACs derive from the application ID (aabb.cc{app}{iface}),
so ids must be unique across opened projects sharing computes — the same
reason IOU has its allocator. IOL Docker nodes draw from the upper half
(512-1022, netiomux's fixed peer is 1023) so the two node types can
neither collide nor starve each other; IOU behavior is unchanged.
The controller sniffs the same GNS3_IOL_RUNNER environment marker the
compute uses to select IOLDockerVM (both the nested-properties and
template/top-level-kwarg shapes), stores the id in node properties like
IOU does, and passes it through the Docker create payload. Without an
allocation the compute falls back to a stable node-derived id in the
same upper range.
This commit is contained in:
8 files changed
+177
-24
No files matched your search
@@ -13,6 +13,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
from gns3server.controller.controller_error import ControllerError
|
||||
|
||||
@@ -20,13 +21,32 @@ import logging
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
# IOU draws from the lower half: uBridge's iol_bridge uses application_id + 512
|
||||
# for its netio peer endpoint. IOL Docker nodes (iol-runner images) draw from
|
||||
# the upper half: their netiomux peer is the fixed id 1023. Both node types
|
||||
# derive interface MACs from the id (aabb.cc{app}{iface}), so the two pools
|
||||
# must stay disjoint — a shared id silently blackholes traffic between the
|
||||
# nodes as a MAC loop.
|
||||
IOU_APPLICATION_ID_POOL = range(1, 512)
|
||||
IOL_DOCKER_APPLICATION_ID_POOL = range(512, 1023)
|
||||
|
||||
def get_next_application_id(projects, computes):
|
||||
|
||||
def is_iol_runner_environment(environment) -> bool:
|
||||
"""
|
||||
Whether a Docker node environment carries the GNS3_IOL_RUNNER marker —
|
||||
the same signal the compute uses to select the IOLDockerVM class.
|
||||
"""
|
||||
|
||||
return "GNS3_IOL_RUNNER=" in (environment or "")
|
||||
|
||||
|
||||
def get_next_application_id(projects, computes, iol_docker=False):
|
||||
"""
|
||||
Calculates free application_id from given nodes
|
||||
|
||||
:param projects: all projects managed by controller
|
||||
:param computes: all computes used by the project
|
||||
:param iol_docker: allocate for an IOL Docker (iol-runner) node instead of IOU
|
||||
:raises HTTPConflict when exceeds number
|
||||
:return: integer first free id
|
||||
"""
|
||||
@@ -38,12 +58,26 @@ def get_next_application_id(projects, computes):
|
||||
if project.status == "opened":
|
||||
nodes.extend(list(project.nodes.values()))
|
||||
|
||||
used = {n.properties["application_id"] for n in nodes if n.node_type == "iou" and n.compute.id in computes}
|
||||
pool = set(range(1, 512))
|
||||
if iol_docker:
|
||||
used = {
|
||||
n.properties["application_id"]
|
||||
for n in nodes
|
||||
if n.node_type == "docker"
|
||||
and n.compute.id in computes
|
||||
and "application_id" in n.properties
|
||||
and is_iol_runner_environment(n.properties.get("environment"))
|
||||
}
|
||||
pool = set(IOL_DOCKER_APPLICATION_ID_POOL)
|
||||
limit = "511 IOL Docker nodes"
|
||||
else:
|
||||
used = {n.properties["application_id"] for n in nodes if n.node_type == "iou" and n.compute.id in computes}
|
||||
pool = set(IOU_APPLICATION_ID_POOL)
|
||||
limit = "512 nodes"
|
||||
try:
|
||||
application_id = (pool - used).pop()
|
||||
return application_id
|
||||
except KeyError:
|
||||
raise ControllerError(
|
||||
"Cannot create a new IOU node (limit of 512 nodes across all opened projects using the same computes)"
|
||||
f"Cannot create a new {'IOL Docker' if iol_docker else 'IOU'} node "
|
||||
f"(limit of {limit} across all opened projects using the same computes)"
|
||||
)
|
||||
Reference in new issue
Block a user