mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-11-03 05:51:15 +02:00
Reload a topology work
This commit is contained in:
14 files changed
+167
-34
No files matched your search
@@ -92,6 +92,7 @@ class Controller:
|
||||
# Preload the list of projects from disk
|
||||
server_config = Config.instance().get_section_config("Server")
|
||||
projects_path = os.path.expanduser(server_config.get("projects_path", "~/GNS3/projects"))
|
||||
os.makedirs(projects_path, exist_ok=True)
|
||||
try:
|
||||
for project_path in os.listdir(projects_path):
|
||||
project_dir = os.path.join(projects_path, project_path)
|
||||
@@ -101,11 +102,10 @@ class Controller:
|
||||
try:
|
||||
yield from self.load_project(os.path.join(project_dir, file), load=False)
|
||||
except aiohttp.web_exceptions.HTTPConflict:
|
||||
pass # Skip not compatible projects
|
||||
pass # Skip not compatible projects
|
||||
except OSError as e:
|
||||
log.error(str(e))
|
||||
|
||||
|
||||
def is_enabled(self):
|
||||
"""
|
||||
:returns: whether the current instance is the controller
|
||||
@@ -219,7 +219,7 @@ class Controller:
|
||||
|
||||
project = yield from self.add_project(path=os.path.dirname(path), status="closed", **topo_data)
|
||||
if load:
|
||||
yield from project.load()
|
||||
yield from project.open()
|
||||
|
||||
@property
|
||||
def projects(self):
|
||||
|
||||
@@ -228,7 +228,19 @@ class Compute:
|
||||
def password(self, value):
|
||||
self._set_auth(self._user, value)
|
||||
|
||||
def __json__(self):
|
||||
def __json__(self, topology_dump=False):
|
||||
"""
|
||||
:param topology_dump: Filter to keep only properties require for saving on disk
|
||||
"""
|
||||
if topology_dump:
|
||||
return {
|
||||
"compute_id": self._id,
|
||||
"name": self._name,
|
||||
"protocol": self._protocol,
|
||||
"host": self._host,
|
||||
"port": self._port,
|
||||
"user": self._user
|
||||
}
|
||||
return {
|
||||
"compute_id": self._id,
|
||||
"name": self._name,
|
||||
|
||||
@@ -55,6 +55,7 @@ class Link:
|
||||
|
||||
if len(self._nodes) == 2:
|
||||
self._project.controller.notification.emit("link.created", self.__json__())
|
||||
self._project.dump()
|
||||
|
||||
@asyncio.coroutine
|
||||
def create(self):
|
||||
@@ -156,7 +157,10 @@ class Link:
|
||||
else:
|
||||
return None
|
||||
|
||||
def __json__(self):
|
||||
def __json__(self, topology_dump=False):
|
||||
"""
|
||||
:param topology_dump: Filter to keep only properties require for saving on disk
|
||||
"""
|
||||
res = []
|
||||
for side in self._nodes:
|
||||
res.append({
|
||||
@@ -164,6 +168,11 @@ class Link:
|
||||
"adapter_number": side["adapter_number"],
|
||||
"port_number": side["port_number"]
|
||||
})
|
||||
if topology_dump:
|
||||
return {
|
||||
"nodes": res,
|
||||
"link_id": self._id
|
||||
}
|
||||
return {
|
||||
"nodes": res,
|
||||
"link_id": self._id,
|
||||
|
||||
@@ -25,6 +25,10 @@ from .compute import ComputeConflict
|
||||
from ..utils.images import images_directories
|
||||
|
||||
|
||||
import logging
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Node:
|
||||
# This properties are used only on controller and are not forwarded to the compute
|
||||
CONTROLLER_ONLY_PROPERTIES = ["x", "y", "z", "symbol", "label", "console_host"]
|
||||
@@ -68,7 +72,11 @@ class Node:
|
||||
}
|
||||
# Update node properties with additional elements
|
||||
for prop in kwargs:
|
||||
setattr(self, prop, kwargs[prop])
|
||||
try:
|
||||
setattr(self, prop, kwargs[prop])
|
||||
except AttributeError as e:
|
||||
log.critical("Can't set attribute %s", prop)
|
||||
raise e
|
||||
|
||||
@property
|
||||
def id(self):
|
||||
@@ -370,7 +378,25 @@ class Node:
|
||||
def __repr__(self):
|
||||
return "<gns3server.controller.Node {} {}>".format(self._node_type, self._name)
|
||||
|
||||
def __json__(self):
|
||||
def __json__(self, topology_dump=False):
|
||||
"""
|
||||
:param topology_dump: Filter to keep only properties require for saving on disk
|
||||
"""
|
||||
if topology_dump:
|
||||
return {
|
||||
"compute_id": str(self._compute.id),
|
||||
"node_id": self._id,
|
||||
"node_type": self._node_type,
|
||||
"name": self._name,
|
||||
"console": self._console,
|
||||
"console_type": self._console_type,
|
||||
"properties": self._properties,
|
||||
"label": self._label,
|
||||
"x": self._x,
|
||||
"y": self._y,
|
||||
"z": self._z,
|
||||
"symbol": self._symbol
|
||||
}
|
||||
return {
|
||||
"compute_id": str(self._compute.id),
|
||||
"project_id": self._project.id,
|
||||
|
||||
@@ -60,7 +60,12 @@ class Project:
|
||||
if path is None:
|
||||
path = os.path.join(get_default_project_directory(), self._id)
|
||||
self.path = path
|
||||
self.reset()
|
||||
|
||||
def reset(self):
|
||||
"""
|
||||
Called when open/close a project. Cleanup internal stuff
|
||||
"""
|
||||
self._allocated_node_names = set()
|
||||
self._nodes = {}
|
||||
self._links = {}
|
||||
@@ -291,7 +296,8 @@ class Project:
|
||||
def close(self):
|
||||
for compute in self._project_created_on_compute:
|
||||
yield from compute.post("/projects/{}/close".format(self._id))
|
||||
self._allocated_node_names.clear()
|
||||
self.reset()
|
||||
self._status = "closed"
|
||||
|
||||
@asyncio.coroutine
|
||||
def delete(self):
|
||||
@@ -324,24 +330,27 @@ class Project:
|
||||
return os.path.join(self.path, filename)
|
||||
|
||||
@asyncio.coroutine
|
||||
def load(self):
|
||||
def open(self):
|
||||
"""
|
||||
Load topology elements
|
||||
"""
|
||||
self.reset()
|
||||
path = self._topology_file()
|
||||
topology = load_topology(path)["topology"]
|
||||
for compute in topology["computes"]:
|
||||
yield from self.controller.add_compute(**compute)
|
||||
for node in topology["nodes"]:
|
||||
compute = self.controller.get_compute(node.pop("compute_id"))
|
||||
name = node.pop("name")
|
||||
node_id = node.pop("node_id")
|
||||
yield from self.add_node(compute, name, node_id, **node)
|
||||
for link_data in topology["links"]:
|
||||
link = yield from self.add_link(link_id=link_data["link_id"])
|
||||
for node_link in link_data["nodes"]:
|
||||
node = self.get_node(node_link["node_id"])
|
||||
yield from link.add_node(node, node_link["adapter_number"], node_link["port_number"])
|
||||
if os.path.exists(path):
|
||||
topology = load_topology(path)["topology"]
|
||||
for compute in topology["computes"]:
|
||||
yield from self.controller.add_compute(**compute)
|
||||
for node in topology["nodes"]:
|
||||
compute = self.controller.get_compute(node.pop("compute_id"))
|
||||
name = node.pop("name")
|
||||
node_id = node.pop("node_id")
|
||||
yield from self.add_node(compute, name, node_id, **node)
|
||||
for link_data in topology["links"]:
|
||||
link = yield from self.add_link(link_id=link_data["link_id"])
|
||||
for node_link in link_data["nodes"]:
|
||||
node = self.get_node(node_link["node_id"])
|
||||
yield from link.add_node(node, node_link["adapter_number"], node_link["port_number"])
|
||||
self._status = "opened"
|
||||
|
||||
def dump(self):
|
||||
"""
|
||||
@@ -362,5 +371,5 @@ class Project:
|
||||
"name": self._name,
|
||||
"project_id": self._id,
|
||||
"path": self._path,
|
||||
"status": "opened"
|
||||
"status": self._status
|
||||
}
|
||||
@@ -43,12 +43,12 @@ def project_to_topology(project):
|
||||
computes = set()
|
||||
for node in project.nodes.values():
|
||||
computes.add(node.compute)
|
||||
data["topology"]["nodes"].append(node.__json__())
|
||||
data["topology"]["nodes"].append(node.__json__(topology_dump=True))
|
||||
for link in project.links.values():
|
||||
data["topology"]["links"].append(link.__json__())
|
||||
data["topology"]["links"].append(link.__json__(topology_dump=True))
|
||||
for compute in computes:
|
||||
if hasattr(compute, "__json__"):
|
||||
data["topology"]["computes"].append(compute.__json__())
|
||||
data["topology"]["computes"].append(compute.__json__(topology_dump=True))
|
||||
#TODO: check JSON schema
|
||||
return data
|
||||
|
||||
|
||||
Reference in new issue
Block a user